Java 線程池

線程池的做用:java

     線程池做用就是限制系統中執行線程的數量。
     根據系統的環境狀況,能夠自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了形成系統擁擠效率不高。用線程池控制線程數量,其餘線程排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務須要運行時,若是線程池中有等待的工做線程,就能夠開始運行了;不然進入等待隊列。
服務器

 

爲何要用線程池:測試

  1. 減小了建立和銷燬線程的次數,每一個工做線程均可以被重複利用,可執行多個任務
  2. 能夠根據系統的承受能力,調整線程池中工做線線程的數目,防止由於由於消耗過多的內存,而把服務器累趴下(每一個線程須要大約1MB內存,線程開的越多,消耗的內存也就越大,最後死機)

線程池類this

package com.tdt.impl.ls;

import java.util.LinkedList;

/**
 * @project LocationGateway
 * @author sunnylocus    
 * @verson 1.0.0
 * @date   Aug 2, 2008
 * @jdk    1.4.2
 */
public class ThreadPool extends ThreadGroup {
    private boolean isClosed = false;  //線程池是否關閉 
    private LinkedList workQueue;      //工做隊列
    private static int threadPoolID = 1;  //線程池的id
    public ThreadPool(int poolSize) {  //poolSize 表示線程池中的工做線程的數量

        super(threadPoolID + "");      //指定ThreadGroup的名稱
        setDaemon(true);               //繼承到的方法,設置是否守護線程池
        workQueue = new LinkedList();  //建立工做隊列
        for(int i = 0; i < poolSize; i++) {
            new WorkThread(i).start();   //建立並啓動工做線程,線程池數量是多少就建立多少個工做線程
        }
    }
    
    /** 向工做隊列中加入一個新任務,由工做線程去執行該任務*/
    public synchronized void execute(Runnable task) {
        if(isClosed) {
            throw new IllegalStateException();
        }
        if(task != null) {
            workQueue.add(task);//向隊列中加入一個任務
            notify();             //喚醒一個正在getTask()方法中待任務的工做線程
        }
    }
    
    /** 從工做隊列中取出一個任務,工做線程會調用此方法*/
    private synchronized Runnable getTask(int threadid) throws InterruptedException {
        while(workQueue.size() == 0) {
            if(isClosed) return null;
            System.out.println("工做線程"+threadid+"等待任務...");
            wait();                //若是工做隊列中沒有任務,就等待任務
        }
        System.out.println("工做線程"+threadid+"開始執行任務...");
        return (Runnable) workQueue.removeFirst(); //反回隊列中第一個元素,並從隊列中刪除
    }
    
    /** 關閉線程池 */
    public synchronized void closePool() {
        if(! isClosed) {
            waitFinish();        //等待工做線程執行完畢
            isClosed = true;
            workQueue.clear();  //清空工做隊列
            interrupt();         //中斷線程池中的全部的工做線程,此方法繼承自ThreadGroup類
        }
    }
    
    /** 等待工做線程把全部任務執行完畢*/
    public void waitFinish() {
        synchronized (this) {
            isClosed = true;
            notifyAll();            //喚醒全部還在getTask()方法中等待任務的工做線程
        }
        Thread[] threads = new Thread[activeCount()]; //activeCount() 返回該線程組中活動線程的估計值。
        int count = enumerate(threads); //enumerate()方法繼承自ThreadGroup類,根據活動線程的估計值得到線程組中當前全部活動的工做線程
        for(int i =0; i < count; i++) { //等待全部工做線程結束
            try {
                threads[i].join();    //等待工做線程結束
            }catch(InterruptedException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * 內部類,工做線程,負責從工做隊列中取出任務,並執行
     * @author sunnylocus
     */
    private class WorkThread extends Thread {
        private int id;
        public WorkThread(int id) {
            //父類構造方法,將線程加入到當前ThreadPool線程組中
            super(ThreadPool.this,id+"");
            this.id =id;
        }
        public void run() {
            while(! isInterrupted()) {  //isInterrupted()方法繼承自Thread類,判斷線程是否被中斷
                Runnable task = null;
                try {
                    task = getTask(id);        //取出任務
                }catch(InterruptedException ex) {
                    ex.printStackTrace();
                }
                //若是getTask()返回null或者線程執行getTask()時被中斷,則結束此線程
                if(task == null) return;
                
                try {
                    task.run();  //運行任務
                }catch(Throwable t) {
                    t.printStackTrace();
                }
            }//  end while
        }//  end run
    }// end workThread
}

2.測試類spa

package com.tdt.test;

import com.tdt.impl.ls.ThreadPool;

public class ThreadPoolTest {
    
    public static void main(String[] args) throws InterruptedException {
        ThreadPool threadPool = new ThreadPool(3); //建立一個有個3工做線程的線程池
        Thread.sleep(500); //休眠500毫秒,以便讓線程池中的工做線程所有運行
        //運行任務
        for (int i = 0; i <=5 ; i++) { //建立6個任務
            threadPool.execute(createTask(i));
        }
        threadPool.waitFinish(); //等待全部任務執行完畢
        threadPool.closePool(); //關閉線程池

    }

    private static Runnable createTask(final int taskID) {
        return new Runnable() {
            public void run() {
            //    System.out.println("Task" + taskID + "開始");
                System.out.println("Hello world");
            //    System.out.println("Task" + taskID + "結束");
            }
        };
    }
}

結果:線程

工做線程0等待任務...
工做線程1等待任務...
工做線程2等待任務...

工做線程0開始執行任務...
Hello world
工做線程0等待任務...

工做線程1開始執行任務...
Hello world
工做線程1等待任務...

工做線程2開始執行任務...
Hello world
工做線程2等待任務...

工做線程0開始執行任務...
Hello world
工做線程0等待任務...

工做線程1開始執行任務...
Hello world
工做線程1等待任務...

工做線程2開始執行任務...
Hello world
工做線程2等待任務...

 

本文轉自:http://sunnylocus.iteye.com/blog/223327?page=2#commentscode

相關文章
相關標籤/搜索