我们知道我们打开个程序(或者说运行一款软件)其实也就是创建了一个进程,只不过程序是静态指令的集合,而进程是正在系统中运行的指令集合,进程是系统进行资源分配与调度的一个独立单位。进程具有独立性,动态性,并发性。现在的操作系统都支持并发,但在具体实现的细节上,根据硬件和操作系统的不同存在不同的策略,比较常用的方式有:共用式的多任务操作策略,抢占式的多任务策略。

线程扩展了进程的概念,线程是进程的执行单元,线程在进程中也是独立存在的,是一种并发的执行流,当进程被初始化之后,主线程就被创建出来了。对于绝大多数程序来说只有一个主线程,我们可以同时创建多条线程顺序执行流也就是线程。也就是说线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。线程可以拥有自己的堆栈,自己的计数器,自己的局部变量等。但他们不在拥有系统资源,而是与其他线程之间共享该进程所拥有的所有的资源。线程用来完成一定的任务,可与其他线程之间共享父进程中的共享变量及部分环境,相互之间协同来完成进程所要完成的工作。

简单来说:一个程序运行后至少有一个进程,一个进程里可以包含多个线程,但至少包含一个线程。

线程的创建和启动:

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例,每条线程的任务就是完成一定的任务,实际就是执行一段程序流,而java使用run方法来封装这段程序流。接下来介绍两种创建线程的方法。

第一种继承Thread类来创建线程类:

1、定义Thread类的子类,并重写Thread类的run方法,这个run方法的方法体就代表了线程需要完成的任务,就是线程执行体了。

2、创建Thread类子类的实例,也就是创建线程对象。

3、用线程的start方法来启动线程。

下面是一个具体的例子:

/**
*
*/
package cn.wan;
/**
* @author Administrator
*
*/
public class TestHread extends Thread{ private int i; public void run()
{
for(;i<20;i++)
{
System.out.println(getName()+""+i);
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub for(int i = 0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+""+i);
if(i== 20)
{
new TestHread().start();
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
new TestHread().start();
}
}
} }

当Java程序运行时,至少会创建一个线程,那就是主线程,主线程的线程执行体不是由run方法来确定的,而是由main方法来确定的。main方法的方法体代表主线程的线程执行体。

第二种实现Runnable接口创建线程类

1、定义Runnable接口的实现类并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体。

2、创建Runnable实现类的实例,并以此实例来作为Thread类的target来创建Thread对象。这个Thread类的实例才是真正的线程对象。

//   创建Runnable接口实现的对象,SecondThread类实现了这个接口,
SecondThread st = new SecondThread();
Thread th = new Thread(st);

下面是一个具体有的例子:

package cn.wan;

public class SecondThread implements Runnable{

    private int i;
@Override
/**
* run方法同样是线程的执行体
*/
public void run() {
// TODO Auto-generated method stub
for(;i<100;i++)
{
// 当线程类实现Runnable接口时
// 如果想获得当前线程,只能用Tread.currentThread()方法
System.out.println(Thread.currentThread().getName()+""+i);
} } /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub for(int i = 0;i<100;i++)
{
System.out.println(Thread.currentThread().getName()+""+i);
if(i== 20)
{
SecondThread st = new SecondThread();
// 通过new Thread(target,name)方法创建新线程
new Thread(st,"first one").start();
System.out.println("AAAAAAAAAAAAAAAAAAAAAAAAAA");
new Thread(st,"second one").start();
}
}
}
}

第一种和第二种方法主要差别在:

第一种

劣势:因为线程类已经继承了Thread类,所以不能再继续继承父类。

优势:编写简单,如果需要访问当前进程只需使用this关键字即可。无需使用Thread.currentThread方法。

第二种

劣势:编写复杂,如果需要访问当前线程需要使用Thread.currentThread方法。

优势:线程类只是继承了Runnable接口,还可以继承其他类。同时多线程可以同时共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况。

最新文章

  1. 北京电子科技学院(BESTI)实验报告4
  2. jQuery下的轮播
  3. 基于正则的INI读写工具类,支持加密解密
  4. Javascript权威指南——第一章Javascript概述
  5. sqlserver行列转换
  6. javascript基础学习(六)
  7. android:android:background=&quot;#00000000&quot;,透明效果
  8. Ubuntu 分辨率调整及操作问题解决
  9. C# Using的用法
  10. React Native控件之Listview
  11. Python_json
  12. MSSQL-最佳实践-Always Encrypted
  13. windows下golang实现Kfaka消息发送及kafka环境搭建
  14. 物联网架构成长之路(28)-Docker练习之MQ中间件(Kafka)
  15. [Easyui - Grid]为easyui的datagrid、treegrid增加表头菜单,用于显示或隐藏列
  16. 回车符与换行符问题——C语言
  17. MYSQL-5.5.37-win32.msi 这个版本得程序包谁有吗 可以给我一下吗?
  18. [Elixir004]通过环境变量(Environment Variables)来管理config
  19. 【python3】——centos7下安装
  20. MyBitis(iBitis)系列随笔之四:多表(多对一查询操作)

热门文章

  1. 在 Ubuntu 12.04 上通过源码安装 Open vSwitch (OVS)
  2. 翻译记忆软件-塔多思TRADO经典教程_4
  3. Java 吸血鬼数字
  4. Android 四大组件之 Activity(一)
  5. 灰度图像二值化-----c++实现
  6. NSDate 时区转换问题
  7. 利用Session完成用户的登录和注销
  8. NDK 编译armebai-v7a的非4字节对齐crash Fatal signal 7 (SIGSEGV) 错误解决
  9. iscsi initiator端Note
  10. libevent个人理解