2012-11-04 80 views
3

我想了解線程池的邏輯,而下面有一個簡單的不正確和不充分執行它:簡單線程池的實現

class ThreadPool { 
    private BlockingQueue<Runnable> taskQueue; 

    public ThreadPool(int numberOfThreads) { 
     taskQueue = new LinkedBlockingQueue<Runnable>(10); 

     for (int i = 0; i < numberOfThreads; i++) { 
      new PoolThread(taskQueue).start(); 
     } 
    } 

    public void execute(Runnable task) throws InterruptedException { 
     taskQueue.put(task); 
    } 
} 


class PoolThread extends Thread { 
    private BlockingQueue<Runnable> taskQueue; 

    public PoolThread(BlockingQueue<Runnable> queue) { 
     taskQueue = queue; 
    } 

    public void run() { 
     while (true) { 
      try { 
       taskQueue.take().run(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

如果有什麼的線程來執行超過TASKQUEUE大小,數量將調用線程被阻止? ThreadPoolExecutor - 這裏我們可以看到,在這種情況下,這是一個被拒絕的執行處理程序的工作,但我仍然不明白它是如何工作的。預先感謝您的幫助。

編輯:阻塞隊列的

設置最大尺寸10

回答

3

如果有什麼的線程執行超過TASKQUEUE數量大小,將調用線程被阻塞?

隊列的大小是沒有運行的任務的數量。通常情況下,即使線程繁忙時它也是空的。具有與線程數匹配的隊列長度沒有意義,並且此時沒有什麼特別的事情發生。

在這裏我們可以看到,在這種情況下,它拒絕的執行處理程序

的拒絕處理的工作,如果隊列滿時,才調用。您的隊列沒有限制,即使您支持此功能也不會被調用。

但是,如果它確實有一個限制並且它支持此功能,則典型行爲是拋出一個異常。你可以讓它做其他的事情,例如阻止,讓當前線程運行任務(這是我的首選)或者忽略任務。

我還是不明白它是如何工作的。

當您向隊列提供()任務時,如果隊列無法接受它,則返回false。發生這種情況時調用被拒絕的執行處理程

4

想象一羣砌磚工(你的線程)建造一堵牆和一堆磚塊(你的BlockingQueue)。

每個瓦工從堆中取出一塊磚,放置它,然後選擇另一塊磚(taskQueue.take()) - 直到堆中有磚塊,磚瓦工會保持繁忙。

一輛卡車不時會到達,用更多的磚塊填滿堆 - 但只有有限的空間樁,如果沒有空間卡車停下來,並等待磚瓦使用足夠的磚塊。

只要堆中有足夠的磚塊(超過磚瓦的數量),您可以放心,所有的磚瓦人員都有足夠的工作能力 - 但是當堆積物開始變空時,磚瓦將不得不停止工作,直到新的磚交付。

你必須選擇適當數量的砌磚工,爲數不多,而且卡車經常會在堆中等待空間,太多而且其中大部分將閒置在等待新磚。

實現明智的,在一般情況下,Java的給你一個線程池,你很少創建自己的 -

ExecutorService threadExecutor = Executors.newFixedThreadPool(3); 

然後調用:

threadExecutor.submit(Runnable...); 

將任務添加到隊列中。