ConcurrentLinkQueue和BlockingQueue

  在併發隊列上,JDK提供了兩種實現,一個是以ConcurrentLinkQueue爲代表的高性能的隊列,一個是以BlockingQueue接口爲代表的阻塞隊列,無論哪種都繼承自Queue
在這裏插入圖片描述
一、ConcurrentLinkedQueue
  ConcurrentLinkedQueue:是一個適用於高併發場景下的隊列,通過無鎖的方式,實現了高併發狀態下的高性能,通常ConcurrentLinkedQueue性能好於BlockingQueue,它是一個基於鏈接節點的無界線程安全隊列。該隊列的元素遵循先進先出的原則,該隊列不允許null元素。
  ConcurrentLinkedQueue重要方法:
    ()和offer()都是加入元素的方法,(ConcurrentLinkedQueue中,這兩個元素沒有任何的區別)
    pull()和peek()都是取頭元素節點,區別在於前者會刪除元素,後者不會
二、BlockingQueue接口
  1、ArrayBlockingQueue:基於數組的阻塞隊列實現,在ArrayBlockingQueue內部,維護了一個定長數組,以便緩存對列中的數據對象,其內部沒有實現讀寫分離,意味着生產和消費不能完全並行,長度是需要定義的,可以指定先進先出或者先進後出,也叫做有界隊列,很多場景都適合使用。
  2、LinkBlockingQueue:基於鏈表的阻塞隊列,同ArrayBlockingQueue類似,其內部維持着一個數據緩衝隊列(該隊列由一個鏈表組成),LinkBlockingQueue之所以能夠高效的處理併發數據,是因爲其內部實現採用分離鎖(讀寫分離兩個鎖),從而實現生產者和消費者操作的完全並行運行。是一個無界隊列。
  3、PriorityBlockingQueue:基於優先級的阻塞隊列(優先級的判斷通過構造函數傳入的Compator對象決定,也就是說傳入隊列的對象必須實現Comparable接口),在實現PriorityBlockingQueue時,內部控制線程同步的鎖採用的公平鎖,是一個無界隊列
  4、DelayQueue:帶有延遲時間的Queue,其中的元素只有當其指定的延遲時間到了,才能夠從隊列中獲取到該元素。DelayQueue中的元素必須實現Delayed接口,DelayQueue是一個沒有限制大小的隊列,應用場景很多,比如對緩存超時的數據進行移除、任務超時處理,空閒連接的關閉等等
  5、SynchronousQueue:一種沒有緩衝的隊列,生產者產生的數據直接會被消費者獲取並且消費
  PriorityBlockingQueue 代碼示例:

public class Task implements Comparable<Task>{
	
	private int id ;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public int compareTo(Task task) {
		return this.id > task.id ? 1 : (this.id < task.id ? -1 : 0);  
	}
	
	public String toString(){
		return this.id + "," + this.name;
	}
	
}

public class UsePriorityBlockingQueue {
	
	public static void main(String[] args) throws Exception{
				
		PriorityBlockingQueue<Task> q = new PriorityBlockingQueue<Task>();
		
		Task t1 = new Task();
		t1.setId(3);
		t1.setName("id爲3");
		Task t2 = new Task();
		t2.setId(4);
		t2.setName("id爲4");
		Task t3 = new Task();
		t3.setId(1);
		t3.setName("id爲1");
		
		//return this.id > task.id ? 1 : 0;
		q.add(t1);	//3
		q.add(t2);	//4
		q.add(t3);  //1
		
		// 1 3 4
		System.out.println("容器:" + q);
		System.out.println(q.take().getId());
		System.out.println("容器:" + q);
//		System.out.println(q.take().getId());
//		System.out.println(q.take().getId());
		
		
	}
}

  DelayQueue代碼示例:

public class Wangmin implements Delayed {  
    
    private String name;  
    //身份證  
    private String id;  
    //截止時間  
    private long endTime;  
    //定義時間工具類
    private TimeUnit timeUnit = TimeUnit.SECONDS;
      
    public Wangmin(String name,String id,long endTime){  
        this.name=name;  
        this.id=id;  
        this.endTime = endTime;  
    }  
      
    public String getName(){  
        return this.name;  
    }  
      
    public String getId(){  
        return this.id;  
    }  
      
    /** 
     * 用來判斷是否到了截止時間 
     */  
    @Override  
    public long getDelay(TimeUnit unit) { 
        //return unit.convert(endTime, TimeUnit.MILLISECONDS) - unit.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    	return endTime - System.currentTimeMillis();
    }  
  
    /** 
     * 相互批較排序用 
     */  
    @Override  
    public int compareTo(Delayed delayed) {  
    	Wangmin w = (Wangmin)delayed;  
        return this.getDelay(this.timeUnit) - w.getDelay(this.timeUnit) > 0 ? 1:0;  
    }  
  
public class WangBa implements Runnable {  
    
    private DelayQueue<Wangmin> queue = new DelayQueue<Wangmin>();  
    
    public boolean yinye =true;  
      
    public void shangji(String name,String id,int money){  
        Wangmin man = new Wangmin(name, id, 1000 * money + System.currentTimeMillis());  
        System.out.println("網名"+man.getName()+" 身份證"+man.getId()+"交錢"+money+"塊,開始上機...");  
        this.queue.add(man);  
    }  
      
    public void xiaji(Wangmin man){  
        System.out.println("網名"+man.getName()+" 身份證"+man.getId()+"時間到下機...");  
    }  
  
    @Override  
    public void run() {  
        while(yinye){  
            try {  
                Wangmin man = queue.take();  
                xiaji(man);  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            }  
        }  
    }  
      
    public static void main(String args[]){  
        try{  
            System.out.println("網吧開始營業");  
            WangBa siyu = new WangBa();  
            Thread shangwang = new Thread(siyu);  
            shangwang.start();  
              
            siyu.shangji("路人甲", "123", 1);  
            siyu.shangji("路人乙", "234", 10);  
            siyu.shangji("路人丙", "345", 5);  
        }  
        catch(Exception e){  
            e.printStackTrace();
        }  
  
    }  
}  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章