生产者-消费者 轮训机制 线程间的通知机制

生产者-消费者
轮训机制

//生产者与消费者
class Memory{ //内存
	public static ArrayList<Integer> arr=new ArrayList<Integer>();
}
public class Demo02 {

	public static void main(String[] args) {
		Random r=new Random();
		new Thread(new Runnable() { //生产者
			@Override
			public void run() {
				while(true){ //轮训
					int temp=r.nextInt(10)+1;
					Memory.arr.add(temp);
					System.out.println("生产了:"+temp);
					//每隔100~900毫秒
					int result=(r.nextInt(9)+1)*100;
					try {
						Thread.sleep(result);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();
		new Thread(new Runnable() {
			@Override
			public void run() { //消费者
				while(true){ //轮训
					try {
						Thread.sleep(800); //每隔800毫秒
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					for(int i:Memory.arr){ //一次性全部消费
						System.out.println("消费了:"+i);
					}
					Memory.arr.clear();
				}
			}
		}).start();
	}

}

  轮训机制也很常用,设计的好也有很多应用场景


线程间的通知机制

wait(),notify()-(notifyAll())

wait和notify是object类的方法,也就是java为所有对象都提供了这两个方法。

wait和notify必须配合syn关键字使用。

wait释放锁,notify不释放锁。

先观察轮训

class ListAdd1 {
	private volatile static List<String> list=new ArrayList<String>();	
	public void add(){
		list.add("oracle");
	}
	public int size(){
		return list.size();
	}
}
public class Demo03 {
	public static void main(String[] args) {
		final ListAdd1 list1=new ListAdd1();
		Thread t1=new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					for(int i=0;i<10;i++){
						list1.add();
						System.out.println("当前线程:"+Thread.currentThread().getName()+"添加了一个元素..");
						Thread.sleep(500);
					}	
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "t1");
		
		Thread t2=new Thread(new Runnable() {
			@Override
			public void run() {
				while(true){
					if(list1.size()==5){
						System.out.println("当前线程收到通知:"+Thread.currentThread().getName()+" list size=5 线程停止..");
						throw new RuntimeException();
					}
				}
			}
		}, "t2");		
		
		t1.start();
		t2.start();
	}
}

  

t2线程一直while(true),我们改进代码:

class ListAdd2 {
	private volatile static List<String> list=new ArrayList<String>();	
	public void add(){
		list.add("oracle and java");
	}
	public int size(){
		return list.size();
	}
}
public class Demo04 {
	public static void main(String[] args) {
		final ListAdd2 list2 = new ListAdd2();
		//1、 实例化出来一个 lock
		//2、当使用wait 和 notify 的时候 , 一定要配合着synchronized关键字去使用
		final Object lock = new Object(); //创建锁
		Thread t1=new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					synchronized (lock) {
						for(int i = 0; i <10; i++){
							list2.add();
							System.out.println("当前线程:"+Thread.currentThread().getName()+"添加了一个元素..");
							Thread.sleep(500);
							if(list2.size()==5){
								System.out.println("已经发出通知..");
								lock.notify(); //不释放锁,t1执行完之后才会释放锁
							}
						}						
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
		}, "t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized (lock) {
					if(list2.size()!=5){
						try {
							lock.wait(); //释放锁
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					System.out.println("当前线程:"+Thread.currentThread().getName()+"收到通知线程停止..");
					throw new RuntimeException();
				}
			}
		}, "t2");	
		t2.start(); //先启动t2
		t1.start();	
	}
}

  

再次写一个生产者与消费者(不要拘泥具体代码)

//wait和notify必须配合synchronized关键字使用
class X{
	public static List<Integer> list=new ArrayList<Integer>();
	public static final Object lock = new Object(); //创建锁
}
class Product implements Runnable{
	Random r=new Random();
	@Override
	public void run() {
		try {
			while(true){
				synchronized (X.lock) {
					while(X.list.size()>=100){
						X.lock.wait();
					}
					int number=(r.nextInt(20)+1); //生产一个小余20的随机数
					X.list.add(number);
					System.out.println("生产了:"+number);
					X.lock.notify();
				}
				int temp=(r.nextInt(11))*100;
				Thread.sleep(temp); //每隔100~1000毫秒
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
class Consumer implements Runnable{
	@Override
	public void run() {
		try {
			while(true){
				synchronized (X.lock) {
					while(X.list.size()==0){
						X.lock.wait();
					}
					
					for(Integer i:X.list){
						System.out.println("消费了"+i);
					}
					X.list.clear(); //清空
					X.lock.notify();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}
}

public class Demo11 {
	public static void main(String[] args) {
		new Thread(new Product()).start(); //生产者启动
		new Thread(new Consumer()).start(); //消费者启动
	}
}

  

原文地址:https://www.cnblogs.com/mengxinrenyu/p/8097896.html