package test.synchornize;
import java.util.concurrent.locks.*;
class runab implements Runnable{
boolean x = true;
static Lock lock = new ReentrantLock();
static Condition con1 = lock.newCondition();
static Condition con2 = lock.newCondition();
runab(boolean x){
this.x = x;
}
public void run() {
lock.lock();
try {
System.out.println("Start---" + Thread.currentThread().getName());
if(x) {
x = false;
try {con1.await();con2.await();} catch (InterruptedException e) {}
}
System.out.println("End---" + Thread.currentThread().getName());
} finally {
con2.signalAll();
con1.signalAll();
lock.unlock();
}
}
}
public class showLock {
public static void main(String[] args) {
runab rab = new runab(true);
runab rab1 = new runab(false);
Thread th = new Thread(rab);
Thread th1 = new Thread(rab1);
th.start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
th1.start();
}
}
请问finally里面怎样写才能,让线程th继续下去呢?(即让程序最后一行输出
“End---Thread-0”)
呵,你这怎么写线程th都执行不下去啊,自己把自己锁死了。con1.await()和con2.await()是释放锁,线程进入阻塞状态并等待其他线程唤醒,finally根本就不会执行,那必然不会唤醒。你这con1和con2就不应该是对象内的局部变量,应该是线程间的共享变量,才能在自己等待的时候,被其他线程唤醒。
我定义的static Condition,static不是可以共享吗?
@剑握在手: 不好意思,之前没看清楚,很少有你这么写的,包括runab的类名竟然是小写开头。我拷贝了你的代码试验了一下,没有输出“End---Thread-0”的原因是这样的:当线程th运行的时候,在con1.await()处等待并释放锁,注意此时并没有运行con2.await()。线程th1运行时由于x为false所以直接进入finally块,首先唤醒阻塞在con2上的线程,但此时并没有线程阻塞在con2上;然后唤醒阻塞在con1上的线程即线程th,等走完lock.unlock()之后,线程th开始接着con1.await()后面执行,也就是con2.await(),再次将自己阻塞,而此时不再有其他线程来唤醒它了。
我不太清楚你的源代码是要解决什么问题,所以没法提出合适的修改意见,如果仅仅是个实验,那明白上面所说的就够了,要使“End---Thread-0”打印出来,在main函数最后再加上一个运行rab1的线程即可,如下(增加了15-22行):
1 public static void main(String[] args) { 2 Runab rab = new Runab(true); 3 Runab rab1 = new Runab(false); 4 Thread th = new Thread(rab); 5 Thread th1 = new Thread(rab1); 6 th.start(); 7 try { 8 Thread.sleep(100); 9 } catch (InterruptedException e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 } 13 th1.start(); 14 15 try { 16 Thread.sleep(100); 17 } catch (InterruptedException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 Thread th2=new Thread(rab1); 22 th2.start(); 23 }
@孟衡: 正是这个原因,非常感谢你的热心帮助。