zoukankan      html  css  js  c++  java
  • 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关键字,这样就省去了自己去维护线程安全

      

  • 相关阅读:
    wordpress建个人博客
    函数(一)
    字符串格式化
    集合运算
    基本数据类型(二)
    基本数据类型(一)
    分享一个下片神器
    Proxyee
    基本运算符
    条件语句和while循环
  • 原文地址:https://www.cnblogs.com/javabg/p/7390153.html
Copyright © 2011-2022 走看看