多线程的通信:代表多个线程之间可以直接进行交互,例如,两个线程互相交替打印数字
涉及到三个方法:wait,notify ,notifyall:
对于生产者消费者问题:
1 package ThreadTest02; 2 3 /** 4 *线程的通信:两个线程之间相互交互,eg:线程交替打印 5 *涉及到的三个方法: 6 * wait()方法:执行此方法,当前线程进入堵塞状态,并释放同步监视器 7 * notify():执行此方法,就会唤醒被wait的一个线程,如果有多个线程被wait,释放优先级最高的那个 8 * notifyAll():执行此方法,就会唤醒所有被wait的方法 9 * 10 * 说明:1:此三个方法必须使用在同步代码块或者同步方法中 11 * 2:此三个方法的调用者必须是同步代码块或同步方法中的同步监视器 12 * sleep():wait()两种方法的异同: 13 * 相同:一旦执行,都会使得当前线程进入堵塞状态 14 * 不同:1;声明的位置不同,sleep声明在thread类中,wait声明在object类中 15 * 2;调用的要求不同,sleep可以随便调用,wait只能在同步代码块或者同步方法中调用 16 * 3;是否释放同步监视器:sleep不会释放锁,wait会释放同步监视器 17 */ 18 public class ThreadCommunication implements Runnable{ 19 private int number=0; 20 @Override 21 public void run() { 22 while (true){ 23 synchronized (this) { 24 this.notifyAll();//唤醒线程 25 if (number <= 100) { 26 System.out.println(Thread.currentThread().getName() + ":" + number); 27 number++; 28 try { 29 //使得调用wait方法的线程进入堵塞状态, 30 wait(); 31 } catch (InterruptedException e) { 32 e.printStackTrace(); 33 } 34 } else { 35 break; 36 } 37 } 38 } 39 } 40 } 41 42 class CTest{ 43 public static void main(String[] args) { 44 ThreadCommunication t1=new ThreadCommunication(); 45 Thread thread1=new Thread(t1); 46 Thread thread2=new Thread(t1); 47 thread1.setName("线程1"); 48 thread2.setName("线程2"); 49 thread1.start(); 50 thread2.start(); 51 } 52 }
1 /** 2 * 生产者与消费者问题: 3 * 生产者将产品交给店员,而消费者从店员处取走产品,店员一次只能持有最多20个产品,如果生产者试图生产更多的产品 4 * 店员就会叫生产者暂停一下,等待消费者去买,如果没有产品了, 5 * 店员会告诉消费者暂停一下,等有产品再让消费者来取走产品 6 * 注意:wait的用法,必须用在同步代码块或者同步方法中,对于同步方法记得加上synchronized关键字 7 */ 8 public class ThreadTest03 { 9 public static void main(String[] args) { 10 Clerk clerk=new Clerk(); 11 Product2 product2=new Product2(clerk); 12 Customer2 customer2=new Customer2(clerk); 13 Thread thread=new Thread(product2); 14 Thread thread1=new Thread(customer2); 15 thread.setName("生产者:"); 16 thread1.setName("消费者:"); 17 thread.start(); 18 thread1.start(); 19 } 20 } 21 class Clerk { 22 private int apple=0; 23 //生产者算法 24 public synchronized void add1(){ 25 if (apple<20){ 26 try { 27 Thread.sleep(200); 28 } catch (InterruptedException e) { 29 e.printStackTrace(); 30 } 31 apple++; 32 System.out.println(Thread.currentThread().getName()+"当前有:"+apple+"个产品"); 33 notify(); 34 }else { 35 try { 36 37 wait(); 38 39 } catch (InterruptedException e) { 40 e.printStackTrace(); 41 } 42 } 43 44 } 45 public synchronized void add2(){ 46 if (apple>0){ 47 try { 48 Thread.sleep(200); 49 } catch (InterruptedException e) { 50 e.printStackTrace(); 51 } 52 apple--; 53 System.out.println(Thread.currentThread().getName()+"当前剩:"+apple+"个产品"); 54 notify(); 55 }else { 56 try { 57 wait();//注意wait方法要要在同步代码块中或者同步方法中 58 } catch (InterruptedException e) { 59 e.printStackTrace(); 60 } 61 } 62 } 63 } 64 class Product2 implements Runnable{ 65 private Clerk clerk; 66 //声明一个clerk类型的对象,将两个类进行连接起来;这样可以共享数据或者方法可以直接通过clerk.来调用 67 //构造器的使用将同一个数据变量进行分享 68 public Product2(Clerk clerk) { 69 this.clerk=clerk; 70 } 71 @Override 72 public void run() { 73 while (true){ 74 clerk.add1(); 75 76 } 77 } 78 79 } 80 81 class Customer2 implements Runnable{ 82 private Clerk clerk; 83 public Customer2(Clerk clerk) { 84 this.clerk=clerk; 85 } 86 87 @Override 88 public void run() { 89 while (true){ 90 clerk.add2(); 91 } 92 } 93 }