Java隊列和定時器Timer


   一: Queue詳解

   Queue: 基本上,一個隊列就是一個先入先出(FIFO)的數據結構

   Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Deque接 口。

  

  1)、沒有實現的阻塞接口的LinkedList: 實現了java.util.Queue接口和java.util.AbstractQueue接口
  內置的不阻塞隊列: PriorityQueue 和 ConcurrentLinkedQueue
  PriorityQueue 和 ConcurrentLinkedQueue 類在 Collection Framework 中加入兩個具體集合實現。 
  PriorityQueue 類實質上維護了一個有序列表。加入到 Queue 中的元素根據它們的天然排序(通過其 java.util.Comparable 實現)或者根據傳遞給構造函數的 java.util.Comparator 實現來定位。
  ConcurrentLinkedQueue 是基於鏈接節點的、線程安全的隊列。並發訪問不需要同步。因為它在隊列的尾部添加元素並從頭部刪除它們,所以只要不需要知道隊列的大 小,ConcurrentLinkedQueue 對公共集合的共享訪問就可以工作得很好。收集關於隊列大小的信息會很慢,需要遍歷隊列。


  2)、實現阻塞接口的:
  java.util.concurrent 中加入了 BlockingQueue 接口和五個阻塞隊列類。它實質上就是一種帶有一點扭曲的 FIFO 數據結構。不是立即從隊列中添加或者刪除元素,線程執行操作阻塞,直到有空間或者元素可用。
五個隊列所提供的各有不同:
  * ArrayBlockingQueue :一個由數組支持的有界隊列。
  * LinkedBlockingQueue :一個由鏈接節點支持的可選有界隊列。
  * PriorityBlockingQueue :一個由優先級堆支持的無界優先級隊列。
  * DelayQueue :一個由優先級堆支持的、基於時間的調度隊列。
  * SynchronousQueue :一個利用 BlockingQueue 接口的簡單聚集(rendezvous)機制。

                    

  下表顯示了jdk1.5中的阻塞隊列的操作:

    add        增加一個元索                     如果隊列已滿,則拋出一個IIIegaISlabEepeplian異常
    remove   移除並返回隊列頭部的元素    如果隊列為空,則拋出一個NoSuchElementException異常
    element  返回隊列頭部的元素             如果隊列為空,則拋出一個NoSuchElementException異常
    offer       添加一個元素並返回true       如果隊列已滿,則返回false
    poll         移除並返問隊列頭部的元素    如果隊列為空,則返回null
    peek       返回隊列頭部的元素             如果隊列為空,則返回null
    put         添加一個元素                      如果隊列滿,則阻塞
    take        移除並返回隊列頭部的元素     如果隊列為空,則阻塞

    3)、示例

 1 package com.svse.queue;
 3 import java.util.LinkedList;
 4 import java.util.Queue;
 7 import java.util.Timer;
 8 import java.util.TimerTask;
10 import com.svse.entity.Users;
11 
12 class TestQueue {
13 
14     static Queue<Users> queueUsers=new LinkedList<Users>();
15     static{
16         Users user1=new Users("201","張三","男","27","歌手");
17         Users user2=new Users("202","李思","女","26","演員");
18         queueUsers.add(user1);
19         queueUsers.add(user2);
20     }
21     
22     public void test1(){
23         
24         Queue<String> queue = new LinkedList<String>();
25         queue.offer("Hello");
26         queue.offer("World!");
27         queue.offer("你好!");
28         
29         System.out.println(queue.size());
30         
31         
32         while (queue.size() > 0) {
33             String element = queue.poll();
34             System.out.println(element);
35         }
36        System.out.println();
37        System.out.println(queue.size());
38     }
39     
40     //生產者
41     public void producerQueue(){
42         
43         System.out.println(queueUsers.size());
44     }
45     
46     //消費者
47     public void consumerQueue(){
48         Users u=null;
49          while((u=queueUsers.poll())!=null){
50                System.out.println(u+" ");
51             }
52        System.out.println();
53        System.out.println(queueUsers.size());
54     }
55    
69     
70     public static void main(String[] args) {
71         TestQueue tq=new TestQueue();
72         //tq.producerQueue();
73         //tq.consumerQueue();
74         
75         timerTest();
76         
77         
78         
79     }
80 
81 }

: 不怕難之BlockingQueue及其實現

  1)、 前言

       BlockingQueue即阻塞隊列,它是基於ReentrantLock,依據它的基本原理,我們可以實現Web中的長連接聊天功能,當然其最常用的還是用於實現生產者與消費者模式,大致如下圖所示:

                                  

 

 

        在Java中,BlockingQueue是一個接口,它的實現類有ArrayBlockingQueue、DelayQueue、 LinkedBlockingDeque、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,它們的區別主要體現在存儲結構上或對元素操作上的不同,但是對於take與put操作的原理,卻是類似的。

  2)、阻塞與非阻塞

  入隊

offer(E e):如果隊列沒滿,立即返回true; 如果隊列滿了,立即返回false-->不阻塞

put(E e):如果隊列滿了,一直阻塞,直到隊列不滿了或者線程被中斷-->阻塞

offer(E e, long timeout, TimeUnit unit):在隊尾插入一個元素,,如果隊列已滿,則進入等待,直到出現以下三種情況:-->阻塞

被喚醒

等待時間超時

當前線程被中斷

  出隊

poll():如果沒有元素,直接返回null;如果有元素,出隊

take():如果隊列空了,一直阻塞,直到隊列不為空或者線程被中斷-->阻塞

poll(long timeout, TimeUnit unit):如果隊列不空,出隊;如果隊列已空且已經超時,返回null;如果隊列已空且時間未超時,則進入等待,直到出現以下三種情況:

被喚醒

等待時間超時

當前線程被中斷

  3)、示例   

 1 package com.yao;
 2 import java.util.concurrent.ArrayBlockingQueue;
 3 import java.util.concurrent.BlockingQueue;
 4 import java.util.concurrent.ExecutorService;
 5 import java.util.concurrent.Executors;
 6 public class BlockingQueueTest {
 7  /**
 8  定義裝蘋果的籃子
 9   */
10  public static class Basket{
11   // 籃子,能夠容納3個蘋果
12   BlockingQueue<String> basket = new ArrayBlockingQueue<String>(3);
13 
14   // 生產蘋果,放入籃子
15   public void produce() throws InterruptedException{
16    // put方法放入一個蘋果,若basket滿了,等到basket有位置
17    basket.put("An apple");
18   }
19   // 消費蘋果,從籃子中取走
20   public String consume() throws InterruptedException{
21    // get方法取出一個蘋果,若basket為空,等到basket有蘋果為止
22    String apple = basket.take();
23    return apple;
24   }
25 
26   public int getAppleNumber(){
27    return basket.size();
28   }
29 
30  }
31  // 測試方法
32  public static void testBasket() {
33   // 建立一個裝蘋果的籃子
34   final Basket basket = new Basket();
35   // 定義蘋果生產者
36   class Producer implements Runnable {
37    public void run() {
38     try {
39      while (true) {
40       // 生產蘋果
41       System.out.println("生產者准備生產蘋果:" 
42         + System.currentTimeMillis());
43       basket.produce();
44       System.out.println("生產者生產蘋果完畢:" 
45         + System.currentTimeMillis());
46       System.out.println("生產完后有蘋果:"+basket.getAppleNumber()+"個");
47       // 休眠300ms
48       Thread.sleep(300);
49      }
50     } catch (InterruptedException ex) {
51     }
52    }
53   }
54   // 定義蘋果消費者
55   class Consumer implements Runnable {
56    public void run() {
57     try {
58      while (true) {
59       // 消費蘋果
60       System.out.println("消費者准備消費蘋果:" 
61         + System.currentTimeMillis());
62       basket.consume();
63       System.out.println("消費者消費蘋果完畢:" 
64         + System.currentTimeMillis());
65       System.out.println("消費完后有蘋果:"+basket.getAppleNumber()+"個");
66       // 休眠1000ms
67       Thread.sleep(1000);
68      }
69     } catch (InterruptedException ex) {
70     }
71    }
72   }
73 
74   ExecutorService service = Executors.newCachedThreadPool();
75   Producer producer = new Producer();
76   Consumer consumer = new Consumer();
77   service.submit(producer);
78   service.submit(consumer);
79   // 程序運行10s后,所有任務停止
80   try {
81    Thread.sleep(10000);
82   } catch (InterruptedException e) {
83   }
84   service.shutdownNow();
85  }
86
87 public static void main(String[] args) { 88 BlockingQueueTest.testBasket(); 89 } 90 }

: 定時器之Timer

 1 package com.svse.queue;
 2 import java.util.Timer;
 3 import java.util.TimerTask;
 4 
 5 public class TestTimer {
 6 
 7 
 8     static int i=0;
 9     public static void timerTest(){
10         //創建一個定時器
11         Timer timer = new Timer();
12         //schedule方法是執行時間定時任務的方法
13         timer.schedule(new TimerTask() {
14             @Override
15             public void run() {
16                 i++;
17                 System.out.println("timerTest: "+i);
18             }
19         }, 1000, 60000); //第一個參數時間 從多少毫秒之后開始執行   第二個時間參數  間隔多少毫秒之后再執行 1分鍾一次
20     }
21 
22     
23     public static void main(String[] args) {
24 
25         timerTest();
26         
27     }
28 
29 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM