java中多線程與線程池的基本使用方法

前言

在java中,如果每個請求到達就創建一個新線程,開銷是相當大的。在實際使用中,服務器在創建和銷毀線程上花費的時間和消耗的系統資源都相當大,甚至可能要比在處理實際的用戶請求的時間和資源要多的多。除瞭創建和銷毀線程的開銷之外,活動的線程也需要消耗系統資源。如果在一個jvm裡創建太多的線程,可能會使系統由於過度消耗內存或“切換過度”而導致系統資源不足。為瞭防止資源不足,服務器應用程序需要采取一些辦法來限制任何給定時刻處理的請求數目,盡可能減少創建和銷毀線程的次數,特別是一些資源耗費比較大的線程的創建和銷毀,盡量利
用已有對象來進行服務,這就是“池化資源”技術產生的原因。

線程池主要用來解決線程生命周期開銷問題和資源不足問題。通過對多個任務重復使用線程,線程創建的開銷就被分攤到瞭多個任務上瞭,而且由於在請求到達時線程已經存在,所以消除瞭線程創建所帶來的延遲。這樣,就可以立即為請求服務,使用應用程序響應更快。另外,通過適當的調整線程中的線程數目可以防止出現資源不足的情況。

多線程大大提高程序運行效率,我們在開發過程中經常會開啟一個線程來執行一些費時的任務。開啟一個線程有4種方式,在下面的文章我將詳細的去講解。

繼承Thread

繼承Thread去執行任務,確實可以開啟一個線程去執行任務,如果經常的去開啟一些線程,也會導致系統資源的浪費。

public static class Mythread extends Thread{
        @Override
        public void run() {
            System.out.println("當前線程"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("運行結果"+i);
        }
    }
//調用線程。
public static void main(String[] args) throws ExecutionException, InterruptedException {
        /**thread執行方式*/
        Mythread mythread = new Mythread();
        mythread.start();//啟動線程
        System.out.println("main--end");
}

實現Runnale接口

public static class MyRunable implements Runnable {

    @Override
    public void run() {
        System.out.println("當前線程"+Thread.currentThread().getId());
        int i = 10/2;
        System.out.println("運行結果"+i);

    }
}

調用。

/**
 * runable的啟動方式
 */

MyRunable runable = new MyRunable();
new Thread(runable).start();
System.out.println("main--end");

Callable

/**
 * Callable可以允許有返回值
 */

public static class Callale01 implements Callable<Integer> {

    @Override
    public Integer call() throws Exception {
        System.out.println("當前線程"+Thread.currentThread().getId());
        int i = 10/2;
        System.out.println("運行結果"+i);
        return i;
    }
}

調用。這裡需要用callable構建futureTask

/**
 * callale的啟動方式
 */
FutureTask<Integer> futureTask =new FutureTask<>(new Callale01());
//取返回結果。
Integer i = futureTask.get();
new Thread(futureTask).start();
System.out.println("返回結果是:"+i);

線程池

線程池才是我們java開發中,經常用到一種開啟多線程的方式,線程池,自己去管理線程。可以節省系統資源。通常我們會將下面的一些配置寫在一些配置類中

/**
 * 七大參數
 * corePoolSize: 1.核心線程數[一直存在]: 線程池創建好瞭以後。就準備就緒的線程數量。
 * maxinumPoolSize: 2 最大線程數量
 * keepaliveTime: 存活時間。空閑線程的最大的等待時間。
 * unit  等待時間的單位
 * blockingQueue 阻塞隊列。如果任務很多就會放在隊列裡面,隻要有線程空閑瞭,就會去隊列裡面去取。
 * threadFactory :線程的工廠。
 * RejectExecutionHandler :如果隊列滿瞭。按照我們指定的策略。拒絕執行任務。
 *
 */
 ThreadPoolExecutor executor = new ThreadPoolExecutor(5,100,10,TimeUnit.SECONDS,
          new LinkedBlockingQueue<>(100),
                                                    Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());

常見的4種線程池。

1 newCachedThreadPool()

創建一個可緩存的線程池,如果線程池長度超過瞭處理的需要,可靈活的回收空閑線程。若無可回收。則創建新線程。

Executors.newCachedThreadPool();

2.newFixedThreadPool(6)

創建一個固定大小的線程池。

3 newScheduledThreadPool()

定時任務的線程池。

4.newSingleThreadExecutor()

Executors.newSingleThreadExecutor();

總結

到此這篇關於java中多線程與線程池基本使用的文章就介紹到這瞭,更多相關java多線程和線程池使用內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: