去故新 Java线程新同步机制
作者:网络转载 发布时间:[ 2013/12/23 11:01:31 ] 推荐标签:
输出:
WorkerTwo:setp into critical section
WorkerTwo:call sayHello()
WorkerOne:step into critical section
2、条件对象Condition,相当于wait-notify机制,提供一种线程间的等待通知机制,condition中的等待-通知方法是await(),signal(),signalAll(),也需要在互斥环境下被调用。
(1) 相关的接口
创建Condition对象,Condition对象是跟Lock关联在一起的。
Lock locker = new ReentrantLock();
Condition cond = locker.newCondition();
把此线程放到条件的等待集中。
void await();
解除此条件的等待集中所有线程的阻塞状态。
void signalAll();
在此条件的等待集中随机选择一个线程,解除其阻塞状态。
void signal();
(2) 使用的基本结构:
//初始时ok_to_proceed为false.
locker.lock()
try{
while(!ok_to_proceed){
//进入等待此条件集中,被阻塞,它维持状态直到另一个线程调用同一个条件上的。
//signalAll/signal方法时为止。
cond.await();
}
}finally{
cker.unlock();
}
locker.lock();
try{
//调用将解除所有等待此条件下的线程的阻塞状态。当线程从等待集中被移走时,它们将再次成为可运行的,调度器将再次激活它们
//此时,它们将试图重新进入对象。一旦锁可获得,它们中的某个线程将从await调用返回,从而获得锁并从它被阻塞的地方继续执行。
ok_to_proceed = true;
cond.signalAll() or cond.signal();
}finally{
locker.unlock();
}
ok_to_proceed也是为了防止wait-notify出现的问题,即再wait之间,notify()已经给出通知,此时wait只会一直等待下去,这样保证了signal()线程的通知被await()线程接收到。
(3) 测试代码:
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class GlobalV{
public final static Lock locker = new ReentrantLock();
public final static Condition cond = locker.newCondition();
public static boolean to_proceed = false;
}
class Response extends Thread{
public void run(){
while(true){
GlobalV.locker.lock();
try{
while(!GlobalV.to_proceed){
GlobalV.cond.await();
}
System.out.println("Response:finish a job");
GlobalV.to_proceed = false;
}catch(Exception e){
e.printStackTrace();
}finally{
GlobalV.locker.unlock();
}
}
}
}
class Request extends Thread{
public void run(){
while(true){
GlobalV.locker.lock();
try{
GlobalV.to_proceed = true;
GlobalV.cond.signalAll();
System.out.println("Request:send a job to Response");
}finally{
GlobalV.locker.unlock();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Test6 {
public static void main(String[] args) {
Request req = new Request();
Response res = new Response();
req.start();
res.start();
}
}

sales@spasvo.com