Java并发编程---使用wait/notify模拟阻塞Queue

 一.BlockingQueue(阻塞Queue)

         1.概念

             顾名思义,首先它是一个队列,并且支持阻塞的机制,阻塞地放入和得到数据.我们要实现LinkedBlockingQueue下面两个简单的方法put和take

            put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续

       take:取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态,直到BlockingQueue有新的数据被加入


     2.代码示例

package com.thread.message;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class MyQueue {
	//1.需要一个承载元素的集合
	LinkedList list = new LinkedList();
	
	//2.需要一个计数器(统计linkedList的个数)
	private AtomicInteger count = new AtomicInteger(0);
	
	//3.需要制约上限和下限
	private final int minSize = 0;
	private int maxSize;
	
	//4.构造方法
	public MyQueue(int size) {
		this.maxSize = maxSize;
	}

	//5.初始化一个对象,用于加锁
	private final Object lock = new Object();
	
	//put(anObject):把anObject加到BlockingQueue里,如果BlockingQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续
	public void put(Object obj){
		synchronized (lock) {
			while(count.get() == this.maxSize){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			//1.加入元素
			list.add(obj);
			//2.计数器累加
			count.incrementAndGet();    //加1后notify
			//通知另外一个线程(唤醒)
			lock.notify();
			System.out.println("新加入的元素为: " + obj);
		}
	}
	
	//take: 取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态,直到BlockingQueue有新的数据被加入
	public Object take(){
		Object ret = null;
		synchronized (lock) {
			while(count.get() == this.maxSize){
				try {
					lock.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			//1.做移除元素操作
			ret = list.removeFirst();
			//2.计数器递减
			count.decrementAndGet();
			//3.唤醒另外一个线程
			lock.notify();
		}
		return ret;
	}
	
	public int getSize(){
		return this.count.get();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final MyQueue mq = new MyQueue(5);
		mq.put("a");
		mq.put("b");
		mq.put("c");
		mq.put("d");
		mq.put("e");
		
		System.out.println("当前容器的长度: " + mq.getSize());
		Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				mq.put("f");
				mq.put("g");
			}
		},"t1");	
		
		t1.start();
		
		Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				Object o1 = mq.take();
				System.out.println("移除的元素为: " + o1);
				Object o2 = mq.take();
				System.out.println("移除的元素为: " + o2);
			}
		},"t2");
		
		try {
			TimeUnit.SECONDS.sleep(2);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		t2.start();
	}

}
 
  
package com.thread.message;

public class ChangLock {
 
	private String lock = "lock";
	
	private void method(){
		synchronized (lock) {     //加锁跟没加锁没区别,因为锁改变了
			try {
				System.out.println("当前线程: " + Thread.currentThread().getName() + "开始");
				lock = "change lock";
				Thread.sleep(2000);
				System.out.println("当前线程: " + Thread.currentThread().getName() + "结束");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
        final ChangLock changLock = new ChangLock();
        Thread t1 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				changLock.method();
			}
		},"t1");
        
        Thread t2 = new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				changLock.method();
			}
		},"t2");
        
        t1.start();
        
        try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        t2.start();
	}

}

package com.thread.message;

/**
 * 死锁问题,在设计程序时就应该避免双方持有对方锁的情况
 * @author Administrator
 *
 */
public class DeadLock implements Runnable {

	private String tag;
	private static Object lock1 = new Object();
	private static Object lock2 = new Object();
	
	public void setTag(String tag){
		this.tag = tag;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
       if(tag.equals("a")){
    	   synchronized (lock1) {
			try {
				System.out.println("当前线程: " + Thread.currentThread().getName() + "进入lock1执行");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized (lock2){
				System.out.println("当前线程: " + Thread.currentThread().getName() + "进入lock2执行");
			}
		}
       }
       
       if(tag.equals("b")){
    	   synchronized (lock2) {
			try {
				System.out.println("当前线程: " + Thread.currentThread().getName() + "进入lock2执行");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized (lock1){
				System.out.println("当前线程: " + Thread.currentThread().getName() + "进入lock1执行");
			}
		}
       }
       
       
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        DeadLock d1 = new DeadLock();
        d1.setTag("a");
        DeadLock d2 = new DeadLock();
        d2.setTag("b");
        
        Thread t1 = new Thread(d1,"t1");
        Thread t2 = new Thread(d2,"t2");
        
        t1.start();
        try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        t2.start();
	}

}

package com.thread.message;

public class ModifyLock {

	private String name;
	private int age;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public synchronized void changeAttributte(String name,int age){	
		try {
			System.out.println("当前线程: " + Thread.currentThread().getName() + "开始");
			this.setName(name);
			this.setAge(age);
			
			System.out.println("当前线程: " + Thread.currentThread().getName() + "修改对象内容为: " + this.name + "," + this.age);
			Thread.sleep(2000);
			System.out.println("当前线程: " + Thread.currentThread().getName() + "结束");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
       final ModifyLock modifyLock = new ModifyLock();
       Thread t1 = new Thread(new Runnable() {	
		@Override
		public void run() {
			// TODO Auto-generated method stub
			modifyLock.changeAttributte("张三", 20);
		 }
	   },"t1");
       
       Thread t2 = new Thread(new Runnable() {	
		@Override
		public void run() {
			// TODO Auto-generated method stub
			modifyLock.changeAttributte("李四", 21);
		 }
	  },"t2");
       
       t1.start();
       try {
		Thread.sleep(1000);
	 } catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	 }
       t2.start();
	}

}

package com.thread.message;

public class ObjectLock {

	public void method1(){
	  synchronized (this) {     //对象锁
		 try {
			 System.out.println("do method1...");
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	  }
	}
	
	public void method2(){            //类锁
		synchronized (ObjectLock.class) {
			try {
				System.out.println("do method2...");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	private Object lock = new Object();
	public void method3(){              //任何对象锁
		synchronized (lock) {
			try {
				System.out.println("do method3...");
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ObjectLock objLock = new ObjectLock();
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				objLock.method1();
			}
		},"t1");
		
		Thread t2 = new Thread(new Runnable() {	
			@Override
			public void run() {
				// TODO Auto-generated method stub
				objLock.method2();
			}
		},"t2");
		
		Thread t3 = new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				objLock.method3();
			}
		},"t3");
	}

}


 

你可能感兴趣的:(Java,并发编程)