您的位置:首页 > 编程语言 > Java开发

Java多线程之阻塞队列

2014-06-01 17:51 405 查看
平时使用的队列是制定好个数以后,如果放入如的数据超过了队列设定的个数就会报错,在java多线程中有一个阻塞队列,这个类是对Queue在多线程中使用的扩展,当作为临界资源的时候,这个队列是安全的,即存放数据如果超过了队列设定好的初始数据的时候,放入数据的线程将会处于等待状态。

public class BlockingQueueTest {
	
	public static void main(String[] args) {
		
		/*创建一个含有三个对象的阻塞队列*/
		final BlockingQueue queue = new ArrayBlockingQueue(3);
		
		for (int i = 0; i < 2; i++) {
			
			new Thread() {
				public void run() {
					while (true) {
						try {
							/*休眠*/
							Thread.sleep((long) (Math.random() * 1000));
							System.out.println(Thread.currentThread().getName() + "准备放数据!");
							/*往队列中添加一个数据*/
							queue.put(1);
							System.out.println(Thread.currentThread().getName() + "已经放了数据," + "队列目前有" + queue.size() + "个数据");
						} catch (InterruptedException e) {
							e.printStackTrace();
						}

					}
				}

			}.start();
		}

		new Thread() {
			public void run() {
				while (true) {
					try {
						/*休眠*/
						Thread.sleep(1000);
						System.out.println(Thread.currentThread().getName() + "准备取数据!");
						/*去数据*/
						queue.take();
						System.out.println(Thread.currentThread().getName() + "已经取走数据," + "队列目前有" + queue.size() + "个数据");
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}

		}.start();
	}
}


我们可以利用阻塞队列的原理来实现不同线程之间的交替执行,思路:使用两个只具有一个空间的队列,队列一满就切换,从而达到子线程执行10次,主线程执行100次,来回切换50次的效果:

public class BlockingQueueCommunication {
	
	public static void main(String[] args) {
		
		final Business business = new Business();
		new Thread(
				new Runnable() {
					
					@Override
					public void run() {
					
						/*子线程总共循环50次*/
						for(int i=1;i<=50;i++){
							business.sub(i);
						}
						
					}
				}
		).start();
		
		/*主线程总共循环50次*/
		for(int i=1;i<=50;i++){
			business.main(i);
		}
		
	}

	 static class Business {
		 
		 
		 /*创建具有一个控件的队列1*/
		  BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
		  /*创建具有两个控件的队列2*/
		  BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
		  
		  /*这是一个默认构造函数*/
		  {
			  //Collections.synchronizedMap(null);
			  try {
				  /*往队列2中添加数据*/
				queue2.put(1);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		  }
		  
		  /**
		   * 子线程执行方法
		   * @param i
		   */
		  public  void sub(int i){
			  	try {
			  		/*往队列1中存数据*/
					queue1.put(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			  	/*子线程循环10次*/
				for(int j=1;j<=10;j++){
					System.out.println("子线程循环: " + j + ",总共循环: " + i);
				}
				try {
					/*从队列2中取数据*/
					queue2.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
		  }
		  
		  /**
		   * 主线程执行方法
		   * @param i
		   */
		  public  void main(int i){
			  	try {
			  		/*往队列2中存数据*/
					queue2.put(1);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			  	/*主线程循环100次*/
				for(int j=1;j<=100;j++){
					System.out.println("主线程循环: " + j + ",总共循环: " + i);
				}
				try {
					/*从队列1中去数据*/
					queue1.take();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
		  }
	  }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: