• Java-Queue总结


    1. ConcurrentLinkedQueue 

    基础链表同步队列。 

    import java.util.Queue;
    import java.util.concurrent.ConcurrentLinkedQueue;
    
    //底层链表实现  队列,先进先出
    public class Test_03_ConcurrentLinkedQueue {
    	public static void main(String[] args) {
    		Queue<String> queue = new ConcurrentLinkedQueue<>();
    		for (int i = 0; i < 10; i++) {
    			queue.offer("value" + i);
    		}
    		System.out.println(queue);
    		System.out.println(queue.size());
    		
    		//peek()  查看queue中的首数据
    		System.out.println(queue.peek());
    		System.out.println(queue.size());
    		
    		//poll()->获取queue首数据
    		System.out.println(queue.poll());
    		System.out.println(queue.size());
    	}
    }
    

       LinkedBlockingQueue 

    阻塞队列,队列容量不足自动阻塞,队列容量为 0 自动阻塞

    import java.util.Random;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.TimeUnit;
    
    /** 并发容器 - LinkedBlockingQueue
    *  阻塞容器。
    *  put & take - 自动阻塞。
    *  put自动阻塞, 队列容量满后,自动阻塞
    *  take自动阻塞方法, 队列容量为0后,自动阻塞。
    */
    public class Test_04_LinkBlockingQueue {
    	final BlockingQueue<String> queue = new LinkedBlockingQueue<>();
    	final Random r = new Random();
    	
    	public static void main(String[] args) {
    		final Test_04_LinkBlockingQueue t = new Test_04_LinkBlockingQueue();
    		
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while(true){
    					try {
    						t.queue.put("value"+t.r.nextInt(1000));
    						TimeUnit.SECONDS.sleep(1);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				}
    			}
    		}, "producer").start();
    		
    		for(int i = 0; i < 3; i++){
    			new Thread(new Runnable() {
    				@Override
    				public void run() {
    					while(true){
    						try {
    							System.out.println(Thread.currentThread().getName() + 
    									" - " + t.queue.take());
    						} catch (InterruptedException e) {
    							e.printStackTrace();
    						}
    					}
    				}
    			}, "consumer"+i).start();
    		}
    	}
    }
    

       ArrayBlockingQueue 

    底层数组实现的有界队列。自动阻塞。根据调用 API(add/put/offer)不同,有不同特 性。 当容量不足的时候,有阻塞能力。 add 方法在容量不足的时候,抛出异常。 put 方法在容量不足的时候,阻塞等待。 offer 方法, 单参数 offer 方法,不阻塞。容量不足的时候,返回 false。当前新增数据操作放弃。 三参数 offer 方法(offer(value,times,timeunit)),容量不足的时候,阻塞 times 时长(单 位为 timeunit),如果在阻塞时长内,有容量空闲,新增数据返回 true。如果阻塞时长范围 内,无容量空闲,放弃新增数据,返回 false

    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.TimeUnit;
    
    public class Test_05_ArrayBlockingQueue {
    	//当容量不足的时候,有阻塞能力
    	//add 方法在容量不足的时候,抛出异常
    	//put 方法在容量不如的时候,阻塞等待
    	//offer 方法,单参数,容量不足的时候,返回false。当前新增数据操作放弃
    	//offer 三参数,容量不足的时候,阻塞times时长(单位为timeunit),如果在阻塞时长内,
    	//有容量空闲,新增数据返回true,如果阻塞时长范围内,无容量空闲,放弃新增数据,返回false
    	
    	final BlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
    
    	public static void main(String[] args) {
    		final Test_05_ArrayBlockingQueue t = new Test_05_ArrayBlockingQueue();
    
    		for (int i = 0; i < 5; i++) {
    			// System.out.println("add method : " + t.queue.add("value"+i));
    			/*
    			 * try { t.queue.put("put"+i); } catch (InterruptedException e) {
    			 * e.printStackTrace(); } System.out.println("put method : " + i);
    			 */
    			// System.out.println("offer method : " + t.queue.offer("value"+i));
    			try {
    				System.out.println("offer method : " + t.queue.offer("value" + i, 1, TimeUnit.SECONDS));
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		System.out.println(t.queue);
    	}
    }
    

      DelayQueue

    延时队列。根据比较机制,实现自定义处理顺序的队列。常用于定时任务。 如:定时关机

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.DelayQueue;
    import java.util.concurrent.Delayed;
    import java.util.concurrent.TimeUnit;
    
    //有顺序有时间的排序
    //延时队列,根据比较机制,实现自定义处理顺序的队列。常用于定时任务
    public class Test_06_DelayQueue {
    	static BlockingQueue<MyTask_06> queue = new DelayQueue<>();
    
    	public static void main(String[] args) throws InterruptedException {
    		long value = System.currentTimeMillis();
    		MyTask_06 task1 = new MyTask_06(value + 2000);
    		MyTask_06 task2 = new MyTask_06(value + 1000);
    		MyTask_06 task3 = new MyTask_06(value + 3000);
    		MyTask_06 task4 = new MyTask_06(value + 2500);
    		MyTask_06 task5 = new MyTask_06(value + 1500);
    
    		queue.put(task1);
    		queue.put(task2);
    		queue.put(task3);
    		queue.put(task4);
    		queue.put(task5);
    
    		System.out.println(queue);
    		System.out.println(value);
    		for (int i = 0; i < 5; i++) {
    			System.out.println(queue.take());
    		}
    	}
    }
    
    class MyTask_06 implements Delayed {
    
    	private long compareValue;
    
    	public MyTask_06(long compareValue) {
    		this.compareValue = compareValue;
    	}
    
    	/**
    	 * 比较大小。自动实现升序 建议和getDelay方法配合完成。
    	 * 如果在DelayQueue是需要按时间完成的计划任务,必须配合getDelay方法完成。
    	 */
    	@Override
    	public int compareTo(Delayed o) {
    		return (int) (this.getDelay(TimeUnit.MILLISECONDS) - o.getDelay(TimeUnit.MILLISECONDS));
    	}
    
    	/**
    	 * 获取计划时长的方法。 根据参数TimeUnit来决定,如何返回结果值。
    	 */
    	@Override
    	public long getDelay(TimeUnit unit) {
    		return unit.convert(compareValue - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    	}
    
    	@Override
    	public String toString() {
    		return "Task compare value is : " + this.compareValue;
    	}
    }
    

       LinkedTransferQueue 

    转移队列,使用 transfer 方法,实现数据的即时处理。没有消费者,就阻塞

    /**
     * 并发容器 - LinkedTransferQueue
     *  转移队列
     *  add - 队列会保存数据,不做阻塞等待。
     *  transfer - 是TransferQueue的特有方法。必须有消费者(take()方法的调用者)。
     *   如果没有任意线程消费数据,transfer方法阻塞。一般用于处理即时消息。
     */
    import java.util.concurrent.LinkedTransferQueue;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.TransferQueue;
    
    public class Test_07_TransferQueue {
    	TransferQueue<String> queue = new LinkedTransferQueue<>();
    
    	public static void main(String[] args) {
    		final Test_07_TransferQueue t = new Test_07_TransferQueue();
    
    		/*
    		 * new Thread(new Runnable() {
    		 * 
    		 * @Override public void run() { try {
    		 * System.out.println(Thread.currentThread().getName() +
    		 * " thread begin " );
    		 * System.out.println(Thread.currentThread().getName() + " - " +
    		 * t.queue.take()); } catch (InterruptedException e) {
    		 * e.printStackTrace(); } } }, "output thread").start();
    		 * 
    		 * try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) {
    		 * e.printStackTrace(); }
    		 * 
    		 * try { t.queue.transfer("test string"); } catch (InterruptedException
    		 * e) { e.printStackTrace(); }
    		 */
    
    		new Thread(new Runnable() {
    
    			@Override
    			public void run() {
    				try {
    					t.queue.transfer("test string");
    					// t.queue.add("test string");
    					System.out.println("add ok");
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    			}
    		}).start();
    
    		try {
    			TimeUnit.SECONDS.sleep(2);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				try {
    					System.out.println(Thread.currentThread().getName() + " thread begin ");
    					System.out.println(Thread.currentThread().getName() + " - " + t.queue.take());
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}, "output thread").start();
    	}
    }
    

      SynchronusQueue 

    同步队列,是一个容量为 0 的队列。是一个特殊的 TransferQueue。 必须现有消费线程等待,才能使用的队列。 add 方法,无阻塞。若没有消费线程阻塞等待数据,则抛出异常。 put 方法,有阻塞。若没有消费线程阻塞等待数据,则阻塞

    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.SynchronousQueue;
    import java.util.concurrent.TimeUnit;
    
    public class Test_08_SynchronusQueue {
    	
    	BlockingQueue<String> queue = new SynchronousQueue<>();
    	
    	public static void main(String[] args) {
    		final Test_08_SynchronusQueue t = new Test_08_SynchronusQueue();
    		
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				try {
    					System.out.println(Thread.currentThread().getName() + " thread begin " );
    					try {
    						TimeUnit.SECONDS.sleep(2);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    					System.out.println(Thread.currentThread().getName() + " - " + t.queue.take());
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}, "output thread").start();
    		
    		/*try {
    			TimeUnit.SECONDS.sleep(3);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}*/
    		// t.queue.add("test add");
    		try {
    			t.queue.put("test put");
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    		System.out.println(Thread.currentThread().getName() + " queue size : " + t.queue.size());
    	}
    
    }
    

      

  • 相关阅读:
    perimeter of squares
    map
    django路由
    for的骚用法
    3和5的倍数相加和
    PeteCake 字典和最小值
    Find the missing letter
    实现简单的ssh功能
    开源运维工具体系
    vsftp在iptables中的配置
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/11810096.html
Copyright © 2020-2023  润新知