同步代码与同步代码块可以实现多线程的同步,JAVA并发框架提供另外了一个框架,它也能实现多线程的同步,即是Lock和Condition,Condition和Lock是配合在一起使用,从字面意思上看,Condition是条件锁,有了锁,为什么要引用条件锁呢?原因有两个:
1.对一个共享资源有读和写的能力,如果读线程或写线程获取了Lock的权力,即有能力进入,但是如果里面没有内容,读也没有用,如果空间已满了,写也写不了,所有还得有条件去判断一下,是不是线程要等待了;
2.提供一种多线程之间的通信机制,类似wait()和nofity()的原理。
看一个例子,就会明白了,还是实现上次的那个生产者和消费者的例子。
我们假设有一个篮子,最多可以放3个苹果,有多个人可以放苹果,也有多个人可以拿走苹果。
1.对一个共享资源有读和写的能力,如果读线程或写线程获取了Lock的权力,即有能力进入,但是如果里面没有内容,读也没有用,如果空间已满了,写也写不了,所有还得有条件去判断一下,是不是线程要等待了;
2.提供一种多线程之间的通信机制,类似wait()和nofity()的原理。
看一个例子,就会明白了,还是实现上次的那个生产者和消费者的例子。
我们假设有一个篮子,最多可以放3个苹果,有多个人可以放苹果,也有多个人可以拿走苹果。
public class Apple {
private String appName ;
public Apple(String appName ){
this.appName =appName ;
}
public String ToString(){
return this .appName ;
}
}
public class Bascket {
List<Apple> bascket= new ArrayList<Apple>(10);
Lock lock = new ReentrantLock();
//条件锁与Lock是相关的
Condition noEmptity =lock .newCondition();
Condition isFull = lock.newCondition();
public void put(Apple app) throws InterruptedException{
//获取锁
lock.lock();
try{
if(bascket .size()>=10){
//等待
isFull.await();
}
bascket.add( app);
//唤醒其它等待线程
noEmptity.signalAll();
}
finally{
lock.unlock();
}
}
public Apple take() throws InterruptedException{
lock.lock();
Apple apple;
try{
if(bascket .size()<=0){
noEmptity.await();
}
apple= bascket.remove(0);
isFull.signalAll();
}
finally{
lock.unlock();
}
return apple ;
}
}
//生产者
public class Producer implements Runnable{
private Bascket bascket ;
private String name ;
public Producer(Bascket bascket ,String name ){
this.bascket =bascket ;
this.name =name ;
}
public void run(){
while(true ){
try {
System. out.println( name+ "produce..");
bascket.put( new Apple("name"+(int )Math.random()*1000));
} catch (InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Thread. sleep(1000);
} catch (InterruptedException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class TestDemo {
public static void main(String args[]){
Bascket bascket= new Bascket();
Consumer c1= new Consumer(bascket ,"c1" );
Producer p1= new Producer(bascket ,"p1" );
Producer p2= new Producer(bascket ,"p2" );
//线程池管理
ExecutorService service = Executors. newCachedThreadPool();
service.execute( c1);
service.execute( p1);
service.execute( p2);
}
}
具体Lock的实现机制将会在源代码中加以分析。