1、基本概念

1.1  线程调用的随机性

1.2 线程的5种状态

   

线程通常都有5种状态:创建、就绪、运行、阻塞和死亡。

       1、创建状态Create:new语句创建的线程对象处于新建状态,此时它和其他java对象一样,仅被分配了内存,没有调用该对象的start()方法之前,这时线程处于创建状态。

等待或睡眠中回来之后,也会处于就绪状态。

       3、运行状态Running:线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入运行状态,开始运行run函数当中的代码。处于这个状态的线程占用CPU,执行程序代码。在并发运行环境中,如果计算机只有一个CPU,那么任何时刻只会有一个线程处于这个状态。     注意:  只有处于就绪状态的线程才有机会转到运行状态。

       4、阻塞状态Blocked:阻塞状态是指线程正在运行的时候,因为某些原因放弃CPU,暂时停止运行。当线程处于阻塞状态时,Java虚拟机不会给线程分配CPU,直到线程重新进入就绪状态,它才会有机会获得运行状态。

阻塞状态分为三种:

1)、等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。

2)、同步阻塞:运行的线程在获取对象同步锁时,若该同步锁被别的线程占用,则JVM会把线程放入锁池中。

Sleep()方法,或者发出I/O请求时,JVM会把线程设为阻塞状态。当Sleep()状态超时、或者I/O处理完毕时,线程重新转入就绪状态。

必须要注意,A线程和B线程中涉及同步方法f,C线程中不涉及同步方法f,

                  A线程获得锁后,B线程在此过程中不会执行方法f, A线程、B线程与C线程会按照CPU线程调度切换执行;

                  A线程释放锁(执行完F方法,后面不再执行F方法)后,B线程与C线程与A线程会按照CPU线程调度切换执行;

 

所以,锁对线程中正要执行的同步方法的继续有影响,但不影响与同步方法无关的线程的执行;即锁只会引起同步阻塞。

 

被调用后线程状态

线程持锁状态(线程中的同步方法)

 

sleep()

当前线程进入阻塞状态

当前线程不会释放同步锁(同步方法被锁在当前线程),也就是说即便其它线程处于可运行状态,但是由于缺乏锁,其它线程会在相应的同步方法处无法继续执行下去,必须等锁

 

wait()/suspend()

当前线程进入等待阻塞状态

当前线程释放同步锁(同步方法在当前线程中被中止执行),即便是该线程被notify唤醒进入就绪状态下,也无法立即继续执行该同步方法,任然需要等锁,直到获得同步锁后,该线程才会继续执行被中断的同步方法。

当在对象上调用wait()方法时,执行该代码的线程立即放弃它在对象上的锁。

然而调用notify()时,并不意味着这时线程会放弃其锁。如果线程任然在完成同步代码,则线程在移出之前不会放弃锁。因此,只要调用notify()并不意味着这时该锁变得可用,只是说明被wait()阻塞的线程进入了就绪状态,是否取得锁还不一定。

yield()

当前线程由运行状态进入就绪状态

当前线程不会释放同步锁

yield不能控制具体的交出CPU的时间,另外,yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会

join()

当前线程进入等待阻塞状态

 

它结束的条件是:1)等待时间到;2)目标线程已经run完

       5)、死亡状态Dead:如果一个线程的run方法 执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪。

 

 

2、基本案例

3、注意问题