首页 > 代码库 > 09 多线程

09 多线程

作者:thoughtInShare 出处:http://www.cnblogs.com/thoughtInShare 欢迎转载,也请保留这段声明。谢谢!

 

1,进程是处于运行中的程序,并具有一定的独立功能,进程是系统进行资源分配和调度的一个独立单位;

线程是轻量级的进程,线程是进程的执行单元;

一个进程可以有多个线程,一个线程必有一个父进程;

线程可以拥有自己的栈,以及程序计数器,但不拥有系统资源;它与父进程的其他线程共享进程拥有的全部资源;

线程是独立的,它并不知道进程中是否有其他线程存在;

线程的执行是抢占式的,并发执行的;

线程的调度和管理由进程本身负责完成;

 一个程序运行后至少有一个进程,一个进程至少有一个线程;

 

2,多线程的优势

(1)进程之间不能共享内存,但线程之间共享内存则非常容易;

(2)系统创建进程是需要为进程分配系统资源,而创建线程则代价小很多,因此使用多线程实现多任务比多进程实现多任务的效率高;

 

3.线程的创建和启动

方式1:继承Thread类穿件线程类

(1)定义Thread类的子类,并重写run()方法,run()描述线程需要完成的任务;

(2)创建Thread子类的实例,即创建了线程对象;

(3)调用线程对象的start()方法来启动线程;

方式2:实现Runnable接口创建线程类

(1)定义Runnable接口的实现类,并重写该接口的run()方法;

(2)创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象;

方式3:使用Callabe和Future创建线程

 

4.线程的生命周期

生命周期的几种状态:新建(New)就绪(Runnable)运行(Running)阻塞(Blocked)死亡(Dead)

(1)当程序使用new关键字创建了一个线程之后,该线程处于新建状态,此时它和其他Java对象一样,仅仅由Java虚拟机为其分配内存,并初始化其成员变量的值;此时线程对象没有表现除任何线程的动态特征;

(2)当线程对象调用了start()之后,该线程处于就绪状态,Java虚拟机为其穿件方法调用栈和线程计数器,此时线程还没开始运行,只是表示该线程可以运行了;至于线程什么时候开始执行,取决于JVM的线程调度器的调度;

(3)如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则线程处与运行状态;

如果计算机只有一个CPU,任何时刻只有一个线程处于运行状态。多处理器的机器上,将有多个线程并行;

对于采用抢占式策略的系统而言,系统会给每个可执行的线程一个小时间片段来处理任务,当时间片用完后,系统会剥夺该线程的系统资源,让其他线程获得执行的机会,在选择下一个线程时,系统会考虑线程的优先级;

当发现如下情况时,线程进入阻塞状态:

(1) 线程调用sleep()主动放弃所占用的系统资源;

(2) 线程调用了一个阻塞式IO方法,在该方法返回之前,该线程被阻塞;

(3) 线程获得一个同步监视器,但该监视器被其他线程所持有;

(4) 线程在等待某个通知;

(5)程序调用线程的suspend方法将该线程挂起;

当前正在执行的线程进入阻塞状态后,其他线程获得执行的机会,被阻塞的线程在合适的机会会重新进入就绪状态,待线程调度器再次调用它;

 

5.线程死亡

(1)run()或call()方法执行完成,线程正常结束;

(2)线程抛出一个未捕获的exception或error;

(3)程序调用stopI();

死亡的线程不能再调用start()方法进行启动;

 

6.控制线程

(1)Join线程

(2)后台线程

(3)线程睡眠

(4)线程让步:

yield(),将该线程转入就绪状态;sleep(),将该线程转入睡眠状态;二者的区别如下:

(1)sleep暂停当前线程后,会给其他线程执行机会,而不理会其他线程的优先级;而yield只会给优先级相同或优先级更高的线程执行机会;

(2)sleep使线程进入阻塞状态,直到经过阻塞时间才会转入就绪状态,而yield只是将线程转入就绪状态;

(3)sleep比yield具有更好的课移植性;

7.设置线程的优先级

8.线程的同步

(1) 当有两个线程并发修改同一文件时就可能造成异常,Java的多线程支持引入同步监视器来解决此问题;通用方法就是同步代码块,

synchronized(obj)

{

//...同步代码块

}

线程开始执行同步代码块之前,必须先获得监视器的锁定;

任何时刻只有一个线程可以获得对同步监视器的锁定,当同步代码块执行完成后,该线程会释放同步监视器的锁定;

(2)同步方法

同步方法,是使用synchronized关键字来修饰某个方法,对于同步方法而言,无须显式指定同步监视器,同步监视器为this,即该对象本身;

(3)同步锁lock

死锁,当两个线程相互等待对方释放同步监视器时就发生死锁

 

9.线程通信

目的是保证线程的协调运行;

 

09 多线程