多线程同步(Lock)

来源:互联网 发布:域名服务器设置 编辑:程序博客网 时间:2024/05/17 22:24

实例

模仿生产者和消费者的模式

 

先来个两个线程的

class ProducerConsumerDemo{public static void main(String[] args){Res r=new Res();Pro in=new Pro(r);Cou out=new Cou(r);Thread t1=new Thread(in);Thread t2=new Thread(out);t1.start();t2.start();}}class Res{private String name;private int count=1;private boolean flag=false;public synchronized void set(String name){if(flag)try{wait();}catch(Exception e){}this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);flag=true;this.notify();}public synchronized void out(){if(!flag)try{wait();}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"消费者"+this.name);flag=false;this.notify();}}class Pro implements Runnable{private Res r;Pro(Res r){this.r=r;}public void run(){while(true){r.set("--商品--");}}}class Cou implements Runnable{private Res r;Cou(Res r){this.r=r;}public void run(){while(true){r.out();}}}

 

 

这样就OK了

 

下面就试试四个线程的,两个线程生产,两个线程消费;

class ProducerConsumerDemo{public static void main(String[] args){Res r=new Res();Pro in=new Pro(r);Cou out=new Cou(r);Thread t1=new Thread(in);Thread t2=new Thread(in);Thread t3=new Thread(out);Thread t4=new Thread(out);t1.start();t2.start();t3.start();t4.start();}}class Res{private String name;private int count=1;private boolean flag=false;public synchronized void set(String name){if(flag)try{wait();}catch(Exception e){}this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);flag=true;this.notify();}public synchronized void out(){if(!flag)try{wait();}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"消费者"+this.name);flag=false;this.notify();}}class Pro implements Runnable{private Res r;Pro(Res r){this.r=r;}public void run(){while(true){r.set("--商品--");}}}class Cou implements Runnable{private Res r;Cou(Res r){this.r=r;}public void run(){while(true){r.out();}}}


但结果是多生产少消费,并不是我们想要的一生产一消费;

 

改良代码

class ProducerConsumerDemo{public static void main(String[] args){Res r=new Res();Pro in=new Pro(r);Cou out=new Cou(r);Thread t1=new Thread(in);Thread t2=new Thread(in);Thread t3=new Thread(out);Thread t4=new Thread(out);t1.start();t2.start();t3.start();t4.start();}}class Res{private String name;private int count=1;private boolean flag=false;public synchronized void set(String name){while(flag)try{wait();}catch(Exception e){}this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);flag=true;this.notifyAll();}public synchronized void out(){while(!flag)try{wait();}catch(Exception e){}System.out.println(Thread.currentThread().getName()+"消费者"+this.name);flag=false;this.notifyAll();}}class Pro implements Runnable{private Res r;Pro(Res r){this.r=r;}public void run(){while(true){r.set("--商品--");}}}class Cou implements Runnable{private Res r;Cou(Res r){this.r=r;}public void run(){while(true){r.out();}}}


对于多个生产者和消费者。

为什么要定义while判断标记。

原因:让被唤醒的线程在一次判断标记。

 

为什么定义notifyAll?

因为需要唤醒对方线程。

以为只用notify,容易出现只唤醒本方线程的情况,导致程序中的所有线程都等待。

 

 

JDK新版中提供了多线程升级解决方案。
将同步Syschronized替换成现实Lock操作;
将Object中的wait, notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
实现了本方只唤醒对方的操作;

import java.util.concurrent.locks.*;class ProducerConsumerDemo2{public static void main(String[] args){Res r=new Res();Pro in=new Pro(r);Cou out=new Cou(r);Thread t1=new Thread(in);Thread t2=new Thread(in);Thread t3=new Thread(out);Thread t4=new Thread(out);t1.start();t2.start();t3.start();t4.start();}}class Res{private String name;private int count=1;private boolean flag=false;private Lock  lock=new ReentrantLock();private Condition  condition_in=lock.newCondition();private Condition  condition_out=lock.newCondition();public void set(String name)throws InterruptedException{lock.lock();try{while(flag)condition_in.await();this.name=name+"---"+count++;System.out.println(Thread.currentThread().getName()+"+++生产者+++"+this.name);flag=true;condition_out.signal();}finally{lock.unlock();//解锁对象一定要执行}}public void out()throws InterruptedException{lock.lock();try{while(!flag)condition_out.await();System.out.println(Thread.currentThread().getName()+"消费者"+this.name);flag=false;condition_in.signal();}finally{lock.unlock();}}}class Pro implements Runnable{private Res r;Pro(Res r){this.r=r;}public void run(){try{while(true){r.set("--商品--");}}catch (InterruptedException e){}}}class Cou implements Runnable{private Res r;Cou(Res r){this.r=r;}public void run(){try{while(true){r.out();}}catch (InterruptedException e){}}}


 

 


 

 

2 0