明天我将参加编程考试。一个主题是线程,它是防止死锁的方法。为了准备,我今天正在做一个旧考试,并参加了这个练习:
如果我们用0而不是1来启动sem2,结果会是什么?
public class Tester{
public static void main(String [] args) throws InterruptedException {
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(0);
Data data = new Data(sem1,sem2);
MyThread thread1 = new MyThread(data);
MyThread thread2 = new MyThread(data);
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println(data);
}
}
class Data{
private volatile int a = 4;
private volatile int b = 1;
private volatile int c = 0;
private Semaphore sem1, sem2;
public Data(Semaphore sem1, Semaphore sem2){
this.sem1 = sem1;
this.sem2 = sem2;
}
public void divideA() throws InterruptedException {
sem1.acquire();
int tmp = a/2;
a = tmp;
sem1.release();
if(a==1){
sem2.release();
}
}
public void multiplyB(){
tmp = b*2;
b = tmp;
}
public void setC() throws InterruptedException{
sem2.acquire();
sem2.release();
int tmp1 = a;
int tmp2 = b;
c = tmp1 * tmp2;
}
public String toString(){
return "Data (a=" +a+", b=" +b+", c="+c+")");
}
}
class MyThread extends thread{
private Data data;
public MyThread(Data data){
this.data=data;
}
public void run(){
try{
data.divideA();
data.multiplyB();
data.setC();
}catch(InterruptedException e){}
}
}
如果我理解了join() - 方法正确,它会将所有线程置于保持状态,除了调用Method的线程,直到该特定线程在run()中完成其进程。
因此在特定代码中,thread2必须等到thread1完成所有的任务,但是在方法setC()中,它尝试从sem2获取许可,因为sem2没有。因此sem1将被搁置。这是否意味着join()方法将结束并且thread2可以再次开始工作?或者这是一个僵局?