2013-01-22 76 views
0

通過閱讀線程池,我非常困惑。我學到了這個概念,他們是如何實際工作的。 但是我在這個部分感到困惑,怎麼編碼呢。如何在線程池中運行代碼的方法

我在網上搜了很多。最後,我得到了一個博客,有代碼,如下,

條件是不使用內置類

代碼1

public class ThreadPool { 

    private BlockingQueue taskQueue = null; 
    private List<PoolThread> threads = new ArrayList<PoolThread>(); 
    private boolean isStopped = false; 

    public ThreadPool(int noOfThreads, int maxNoOfTasks){ 
    taskQueue = new BlockingQueue(maxNoOfTasks); 

    for(int i=0; i<noOfThreads; i++){ 
     threads.add(new PoolThread(taskQueue)); 
    } 
    for(PoolThread thread : threads){ 
     thread.start(); 
    } 
    } 

    public void synchronized execute(Runnable task){ 
    if(this.isStopped) throw 
     new IllegalStateException("ThreadPool is stopped"); 

    this.taskQueue.enqueue(task); 
    } 

    public synchronized void stop(){ 
    this.isStopped = true; 
    for(PoolThread thread : threads){ 
     thread.stop(); 
    } 
    } 

} 

代碼2

public class PoolThread extends Thread { 
    private BlockingQueue taskQueue = null; 
    private boolean  isStopped = false; 
    public PoolThread(BlockingQueue queue){ 
    taskQueue = queue; 
    } 
    public void run(){ 
    while(!isStopped()){ 
     try{ 
     Runnable runnable = (Runnable) taskQueue.dequeue(); 
     runnable.run(); 
     } catch(Exception e){ 
     //log or otherwise report exception, 
     //but keep pool thread alive. 
     } 
    } 
    } 
    public synchronized void stop(){ 
    isStopped = true; 
    this.interrupt(); //break pool thread out of dequeue() call. 
    } 
    public synchronized void isStopped(){ 
    return isStopped; 
    } 
} 

代碼3: -

public class BlockingQueue { 

    private List queue = new LinkedList(); 
    private int limit = 10; 

    public BlockingQueue(int limit){ 
    this.limit = limit; 
    } 

    public synchronized void enqueue(Object item) 
    throws InterruptedException { 
    while(this.queue.size() == this.limit) { 
     wait(); 
    } 
    if(this.queue.size() == 0) { 
     notifyAll(); 
    } 
    this.queue.add(item); 
    } 

    public synchronized Object dequeue() 
    throws InterruptedException{ 
    while(this.queue.size() == 0){ 
     wait(); 
    } 
    if(this.queue.size() == this.limit){ 
     notifyAll(); 
    } 

    return this.queue.remove(0); 
    }  
} 

我試着理解,這段代碼做了什麼。 但我沒有得到這個代碼的流程。你能幫我理解這段代碼嗎?

Mainly I have problems in **Code 2 :- run method** 

Why execute method's argument are of Runnable type? 

How input array given to this code?? 

幫幫我。

在此先感謝。

+1

爲什麼你必須編寫自己的線程池?最容易使用執行者。* ThreadPool()方法創建一個線程池,然後使用提交(*)方法來提交Callable或Runnable。 – allprog

+0

@allprog:我創建了該代碼,該代碼很容易構建。但是,我的老師要求在不使用內置課程的情況下進行構建。這就是爲什麼我發佈這個。 – devsda

+0

不錯,你讓社區檢查作業。 :)不幸的是,執行ExecutorService的權利很難。如果您提供取消異步Future接口,那麼您必須非常小心。您應該查看JDK源代碼以獲得正確的實現。這將比現在複雜得多。 – allprog

回答

2
public void run(){ 
    while(!isStopped()){ 

循環,直到線程池已停止。

 try{ 
     Runnable runnable = (Runnable) taskQueue.dequeue(); 

將頭任務從任務隊列中拉出。

 runnable.run(); 

運行該任務。

 } catch(Exception e){ 
     //log or otherwise report exception, 
     //but keep pool thread alive. 

如果任務拋出異常,只是不要傳遞它什麼都不做。

 } 
    } 
    } 
+0

'public PoolThread(BlockingQueue queue){ taskQueue = queue; }' 據我所知,這些行的作品是給所有線程工作者提供taskqueue的副本。我對嗎 ? – devsda

+0

告訴我更多的事情,我們如何給**代碼1 **給予inut數組。 因爲要開始我們必須調用代碼1的執行方法。 – devsda

+0

@FreakyCheeky:第一個問題:是的。每個線程獲取對同一隊列的引用。第二個問題:您調用execute函數並將任務放到共享隊列中。 –

1

編輯:

我現在明白了,這是一類項目,但我會離開我爲後人的答案。

如果你想Java中使用線程池,然後這一切已經爲您在java.util.concurrent.*類已經實現。其他答案解決和解釋你的具體代碼。

例如,您需要使用ExecutorService代碼設置線程池。在封面下面,ExecutorService處理線程並使用LinkedBlockingQueue。您定義了實現'Runnable'的類MyJob,並執行池中線程運行的工作。根據您的需要,它可以是短期或長期運行的任務。

// create a thread pool with 10 workers 
ExecutorService threadPool = Executors.newFixedThreadPool(10); 
// or you can create an open-ended thread pool 
// ExecutorService threadPool = Executors.newCachedThreadPool(); 
// define your jobs somehow 
for (MyJob job : jobsToDo) { 
    threadPool.submit(job); 
} 
// once we have submitted all jobs to the thread pool, it should be shutdown 
threadPool.shutdown(); 
... 
public class MyJob implements Runnable { 
    // you can construct your jobs and pass in context for them if necessary 
    public MyJob(String someContext) { 
     ... 
    } 
    public void run() { 
     // process the job 
    } 
} 
+0

其實我是通過使用內置類來創建這段代碼的,但是我的老師跟我說要自己做這個,不用內置類 – devsda

相關問題