使用wait和notify方法實作消費者生産者例子。
首先設計一個生産者類:
package com.freshbin.day2.two;
import java.util.LinkedList;
import java.util.List;
/**
* 生産者類
*
* @author freshbin
* @date 2019年2月26日 下午3:31:57
*/
public class Producer implements Runnable {
private List<Integer> myList;
private Integer size;
public static int count = 50;
public static boolean isBreak = false;
public Producer(List<Integer> myList, Integer size) {
this.myList = myList;
this.size = size;
}
@Override
public void run() {
try {
while(true) {
if(Consumer.isBreak) {
System.out.println("消費者線程已中斷!生産者也自動中斷!");
break;
}
if(Thread.currentThread().isInterrupted()) {
System.out.println("生産者線程中斷!");
isBreak = true;
break;
}
synchronized (myList) {
if(myList.size() >= size) {
System.out.println("已經滿了!");
myList.notifyAll();
myList.wait();
} else {
count--;
int number = (int)(Math.random()*10);
myList.add(number);
System.out.println("生産了一個:" + number);
if(count <= 0) {
System.out.println("生産者達到最大次數!");
myList.notifyAll();
Thread.currentThread().interrupt();
}
myList.notifyAll();
}
}
if(!Thread.currentThread().isInterrupted()) {
Thread.sleep(100);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
消費者類:
package com.freshbin.day2.two;
import java.util.LinkedList;
import java.util.List;
/**
* 消費者類
*
* @author freshbin
* @date 2019年2月26日 下午3:31:57
*/
public class Consumer implements Runnable {
private List<Integer> myList;
public static int count = 50;
public static boolean isBreak = false;
public Consumer(List<Integer> myList) {
this.myList = myList;
}
@Override
public void run() {
try {
while(true) {
if(Producer.isBreak) {
System.out.println("生産者線程已中斷!消費者也自動中斷!");
break;
}
if(Thread.currentThread().isInterrupted()) {
System.out.println("消費者線程中斷!");
isBreak = true;
break;
}
synchronized (myList) {
if(myList.size() > 0) {
count--;
int number = myList.get(myList.size() - 1);
myList.remove(myList.size()-1);
System.out.println("消費了一個:" + number);
if(count <= 0) {
System.out.println("消費者次數達到最大!");
myList.notifyAll();
Thread.currentThread().interrupt();
}
myList.notifyAll();
} else {
System.out.println("沒有數量了!");
myList.notifyAll();
myList.wait();
}
}
if(!Thread.currentThread().isInterrupted()) {
Thread.sleep(100);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
用戶端主類:
package com.freshbin.day2.two;
import java.util.LinkedList;
import java.util.List;
/**
* 2.使用 wait notify 實作一個隊列,隊列有2個方法,add 和 get 。
* add方法往隊列中添加元素,get方法往隊列中獲得元素。隊列必須是線程安全的。
* 如果get執行時,隊列為空,線程必須阻塞等待,直到有隊列有資料。
* 如果add時,隊列已經滿,則add線程要等待,直到隊列有空閑空間。
* 實作這麼一個隊列,并寫一個測試代碼,使他工作在多線程的環境下,證明,它的工作是正确的。
*
* @author freshbin
* @date 2019年2月26日 下午3:05:41
*/
public class Two {
public static void main(String[] args) throws InterruptedException {
List<Integer> myList = new LinkedList<>();
for(int i = 0; i < 5; i++) {
myList.add(i);
}
Thread producer = new Thread(new Producer(myList, 5));
producer.start();
Thread consumer = new Thread(new Consumer(myList));
consumer.start();
}
}
控制台列印:
github位址:https://github.com/freshbin/ThreadDemo/tree/master/src/com/freshbin/day2/two