线程的死锁
在Java编程中,由于线程可进入阻塞状态,也因为对象可拥有synchronized()函数,致使只有在同步锁被释放时,才能够访问对象。因此,可能会出现线程A陷入对线程B的等待,线程B陷入对线程C的等待,线程C又陷入对线程A的等待,于是各个线程陷入一个彼此等待的轮回中,任何线程都动弹不得,这种现象便称为死锁。
一旦发生下面四种情况之一,就会导致死锁发生:
1)相互排斥:一个线程永远占有某一共享资源。
2)循环等待:线程A等线程B,线程B等线程C,线程C等线程A。
3)部分分配:资源被部分分配。例如:线程A和线程B都需要访问一个文件,并且都要用到打印机,线程A获得了文件资源,线程B获得了打印机资源,但是两个线程不能获得全部资源。
4)缺少优先权:一个线程访问了某个资源,但是一直不释放该资源,即使该线程处于阻塞状态。
如果上面四种情况都不出现,系统就不会发生死锁。
线程的联合
一个线程A在占有CPU资源期间,可以让其他线程调用join()方法和本线程联合,如B.join(); 此时称A在运行期间联合了B。如果线程A在占有CPU期间一旦联合线程B,那么线程A立刻中断执行,一直等到它联合的线程B执行完毕,A再重新排队等待CPU资源。如果A准备联合的B已经结束,那么B.join()不会产生任何效果。
在主线程中创建三个线程:“客车司机”,“乘客”和“售票员”。要求线程“客车司机”,占有CPU资源后立刻联合线程“乘客”,也就是让线程“客车司机”一直等到线程“乘客”上车后才能开车;而线程“乘客”占有CPU资源后立刻联合线程“售票员”,也就是让线程“乘客”向线程“售票员”购票后才能下车。
package com.thread;
public class MultiThread_ThreadJoin {
public static void main(String[] args) {
Bus bus = new Bus();
bus.driver.start();
}
}
class Bus implements Runnable{
Thread passenger,driver,conductor;
Bus(){
passenger = new Thread(this);
driver = new Thread(this);
conductor = new Thread(this);
}
public void run(){
if(Thread.currentThread()==passenger){
System.out.println("乘客上车");
try{
conductor.start();
conductor.join();
}catch(InterruptedException e){}
}
else if(Thread.currentThread()==driver){
try{
passenger.start();
passenger.join();
}catch(InterruptedException e){}
System.out.println("发车");
}
else if(Thread.currentThread()==conductor){
System.out.println("购票");
try{
Thread.sleep(1000);
}catch(InterruptedException e){}
}
}
}