java线程通信
用输入和输出两个线程对同一对象进行操作
1 package javase; 2 3 class Resource{ 4 private String name; 5 private String sex; 6 private boolean flag = true; 7 8 public synchronized void set(String name,String sex) { 9 this.name = name; 10 this.sex = sex; 11 } 12 13 public boolean isFlag() { 14 return flag; 15 } 16 17 public void setFlag(boolean flag) { 18 this.flag = flag; 19 } 20 21 public synchronized void get() { 22 System.out.println(name+"------"+sex); 23 } 24 } 25 26 class Output implements Runnable{ 27 28 Resource r; 29 public Output(Resource r) { 30 super(); 31 this.r = r; 32 } 33 34 @Override 35 public void run() { 36 37 r.setFlag(true); 38 while(true) { 39 40 synchronized (r) { 41 if(r.isFlag()) { 42 r.get(); 43 r.setFlag(false); 44 r.notify(); 45 } 46 try { 47 r.wait(); 48 } catch (InterruptedException e) { 49 e.printStackTrace(); 50 } 51 52 } 53 } 54 55 } 56 57 } 58 59 class Input implements Runnable{ 60 61 private int x=0; 62 Resource r; 63 public Input(Resource r) { 64 super(); 65 this.r = r; 66 } 67 68 @Override 69 public void run() { 70 71 while(true) { 72 synchronized (r) { 73 74 if(r.isFlag()) 75 try { 76 r.wait(); 77 } catch (InterruptedException e) { 78 e.printStackTrace(); 79 } 80 if(x%2==0) 81 r.set("佩奇", "母猪"); 82 else 83 r.set("乔治", "公猪"); 84 x++; 85 r.setFlag(true); 86 r.notify(); 87 } 88 } 89 90 } 91 92 } 93 94 public class ResourceDemo { 95 96 public static void main(String[] args) { 97 98 Resource r = new Resource(); 99 Input in = new Input(r); 100 Output out = new Output(r); 101 102 Thread t1 = new Thread(in); 103 Thread t2 = new Thread(out); 104 105 t1.start(); 106 t2.start(); 107 108 } 109 110 }
创建一个公用的对象给两个线程使用,一个为输入,一个为输出。当输入线程进入锁后会对对象元素进行赋值,唤醒锁对象线程池中的任意一个线程,然后使自己进入等待。此时输出线程拿到执行权,输出对象元素的值,再唤醒锁对象线程池中的任意一个线程,然后使自己进入等待。如此不断循环即可
多生产者多消费者案例
1 package javase; 2 3 import java.util.concurrent.locks.Condition; 4 import java.util.concurrent.locks.Lock; 5 import java.util.concurrent.locks.ReentrantLock; 6 7 class Resources{ 8 9 private String name; 10 private int count = 1; 11 private boolean flag = false; 12 13 Lock lock = new ReentrantLock(); 14 15 Condition producer_con = lock.newCondition(); 16 Condition consumer_con = lock.newCondition(); 17 18 public void setName(String name) { 19 20 lock.lock(); 21 try { 22 while(flag) 23 try { 24 producer_con.await(); 25 } catch (InterruptedException e) { 26 e.printStackTrace(); 27 } 28 29 this.name = name + count; 30 System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name); 31 count++; 32 flag = true; 33 consumer_con.signal(); 34 } 35 finally { 36 lock.unlock(); 37 } 38 39 40 } 41 42 public void get() { 43 44 lock.lock(); 45 try { 46 while(!flag) 47 try { 48 consumer_con.await(); 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } 52 53 System.out.println(Thread.currentThread().getName()+"----消费者--"+this.name); 54 flag = false; 55 producer_con.signal(); 56 } 57 finally { 58 lock.unlock(); 59 } 60 61 62 63 } 64 65 } 66 67 class Consumer implements Runnable{ 68 69 private Resources r; 70 public Consumer(Resources r) { 71 super(); 72 this.r = r; 73 } 74 75 @Override 76 public void run() { 77 while(true) 78 r.get(); 79 } 80 81 } 82 83 class Producer implements Runnable{ 84 85 private Resources r; 86 public Producer(Resources r) { 87 super(); 88 this.r = r; 89 } 90 91 @Override 92 public void run() { 93 while(true) 94 r.setName("烤鸭"); 95 } 96 97 } 98 99 public class ProducerConsumerDemo { 100 101 public static void main(String[] args) { 102 103 Resources r = new Resources(); 104 105 Producer p = new Producer(r); 106 Consumer c = new Consumer(r); 107 108 Thread t0 = new Thread(p); 109 Thread t1 = new Thread(p); 110 Thread t2 = new Thread(c); 111 Thread t3 = new Thread(c); 112 113 t0.start(); 114 t1.start(); 115 t2.start(); 116 t3.start(); 117 118 } 119 120 }
生产者每生产一个,消费者就消费一次。用Lock lock = new ReentrantLock();创建锁对象,用其中的方法创建两个监视器,用于分别监视消费者和生产者。开启线程后,生产者生产之前每次都会检查是否有物品,若有则进入等待,同时唤醒消费者线程。若没有则进行生产。消费者消费之前每次都会检查是否有物品。若有则消费。若没有则进入等待,同时唤醒生产者线程。