Java多线程的集合类

适用于多线程环境下的集合类:

1、阻塞队列:ArrayBlockingQueue(数组实现队列),LinkedBlockingQueue(链表实现队列)

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 {
						//将此处的睡眠时间分别改为100和1000,观察运行结果
						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();			
	}
}

 2、阻塞队列线程间通信,如下通过阻塞队列也可以实现线程间通信,你一下我一下的间隔运行,这就是利用阻塞队列的阻塞方法put和take,其实用lock的等待唤醒也照样可以实现 

	 static class Business {  
		  BlockingQueue<Integer> queue1 = new ArrayBlockingQueue<Integer>(1);
		  BlockingQueue<Integer> queue2 = new ArrayBlockingQueue<Integer>(1);
		  
		  {//匿名构造方法,任何构造方法调用之前都会走匿名构造方法块
		  //加static的话是静态代码块,只在类加载时运行一次
			  Collections.synchronizedMap(null);
			  try {
				  System.out.println("xxxxxdfsdsafdsa");
				queue2.put(1);//一上来queue2放满
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		  }
		  
		  public  void sub(int i){
			  	try {
					queue1.put(1);//queue1没满放进去一个,进入下面代码,取走queue2,queue2空出
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int j=1;j<=10;j++){
					System.out.println("sub thread sequece of " + j + ",loop of " + i);
				}
				try {
					queue2.take();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  }
		  
		  public  void main(int i){
			  	try {
					queue2.put(1);//上来时queue2已满,放不进等着queue1取数据,只要一空立马插入一个
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				for(int j=1;j<=100;j++){
					System.out.println("main thread sequece of " + j + ",loop of " + i);
				}
				try {
					queue1.take();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		  }
	  }
}

其他适用于多线程的集合类都位于java.util.concurrent包下,普通的集合不适合多线程操作,如Array,HashMap等,适合多线程的集合有ConcurrentHashMap等,JDK1.5之前没有并发的集合,这时一般通过Collections集合工具类想的不同同步方法,如synchronizedMap来把普通HashMap转为线程安全的加锁的HashMap,但是效率低了,所以操作多线程时推荐使用JDK1.5之后的java.util.concurrent包下的多线程集合,其是部分加锁,而不是所有方法加锁,所以效率比1.5之前的高些,同样的还有8大数据类型的对应线程安全类型,前面都是加atomic的,位于java.util.concurrent.atomic包下,如AtomicInteger,其内部自己维护了多线程操作时的++和--,内部也就是自己加了synchronized关键字,这样就省去了自己去维护线程安全

  

 

posted @ 2017-08-18 15:57  关键步就几步  阅读(748)  评论(0编辑  收藏  举报