多線程編程2

package learn.threadpool;

public class MemberService extends Thread {
    @Override
    public void run() {
        long l1=System.currentTimeMillis();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long l2=System.currentTimeMillis();
        System.out.println("member service...."+(l2-l1));
    }
}

package learn.threadpool;

public class OrderService extends Thread {
    @Override
    public void run() {
        long l1=System.currentTimeMillis();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        long l2=System.currentTimeMillis();
        System.out.println("order service...."+(l2-l1));
    }
}
package learn.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {
    public static void main(String[] args) {
        ExecutorService pool= Executors.newCachedThreadPool();
        Thread t1=new MemberService();
        Thread t2=new OrderService();
        long l1=System.currentTimeMillis();
        pool.execute(t1);
        pool.execute(t2);
        pool.shutdown();
        long l2=System.currentTimeMillis();
        System.out.println(l2-l1);
    }
}

執行結果 :

1
member service....2000
order service....2000

可以發現後兩句話是同時執行的


newCachedThreadPool
創建一個可緩存的線程池。如果線程池的大小超過了處理任務所需要的線程, 那麼就會回收部分空閒(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。

此線程池不會對線程池大小做限制,線程池大小完全依賴於操作系統(或者說JVM)能夠創建的最大線程大小。



package learn.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {
    public static void main(String[] args) {
        ExecutorService pool= Executors.newFixedThreadPool(1);
        Thread t1=new MemberService();
        Thread t2=new OrderService();
        long l1=System.currentTimeMillis();
        pool.execute(t1);
        pool.execute(t2);
        pool.shutdown();
        long l2=System.currentTimeMillis();
        System.out.println(l2-l1);
    }
}


執行結果:

1

member service....2000

order service....2000

可以發現member service....2000先執行,再2s後執行order service....2000


newFixedThreadPool

創建固定大小的線程池。每次提交一個任務就創建一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因爲執行異常而結束,那麼線程池會補充一個新線程。


package learn.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestMain {
    public static void main(String[] args) {
        ExecutorService pool= Executors.newSingleThreadExecutor();
        Thread t1=new MemberService();
        Thread t2=new OrderService();
        long l1=System.currentTimeMillis();
        pool.execute(t2);
        pool.execute(t1);
        pool.shutdown();
        long l2=System.currentTimeMillis();
        System.out.println(l2-l1);
    }
}

執行結果:

1

member service....2000

order service....2000

可以發現member service....2000先執行,再2s後執行order service....2000


 newSingleThreadExecutor
創建一個單線程的線程池。這個線程池只有一個線程在工作,也就是相當於單線程串行執行所有任務。

如果這個唯一的線程因爲異常結束,那麼會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。



newScheduledThreadPool 創建一個定長線程池,支持定時及週期性任務執行。這裏就不演示了。


如何在線程池中的線程都執行完畢後再實現某些方法

package learn.threadpool;

import java.util.concurrent.*;

public class TestMain {
    public static void main(String[] args) {
       ExecutorService pool=Executors.newFixedThreadPool(10);
       pool.execute(new MemberService());
       pool.execute(new OrderService());
       pool.shutdown();
       while(true){
           if(pool.isTerminated()){
               System.out.println("線程池中的線程執行完畢");
               break;
           }
       }




    }

}

輸出結果:

order service....2000
member service....2000
線程池中的線程執行完畢


用countDownLatch方式:

package learn.threadpool;

import java.util.concurrent.CountDownLatch;

public class MemberService extends Thread {
    private CountDownLatch cdl;

    public MemberService(CountDownLatch cdl) {
        this.cdl = cdl;
    }

    @Override
    public void run() {

        long l1=System.currentTimeMillis();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            cdl.countDown();
        }
        long l2=System.currentTimeMillis();
        System.out.println("member service...."+(l2-l1));
    }
}
package learn.threadpool;

import java.util.concurrent.*;

public class TestMain {
    public static void main(String[] args) throws InterruptedException {
        final int threadNum=10;
       ExecutorService pool=Executors.newFixedThreadPool(threadNum);
       final CountDownLatch cdl=new CountDownLatch(threadNum);
       for(int i=0;i<10;i++){
           Thread t=new MemberService(cdl);
           pool.execute(t);
       }
       cdl.await();
        System.out.println("end...");
    }

}

CountDownLatch性能很差

更優雅的方法:

package learn.threadpool;

import java.util.concurrent.*;

public class TestMain {
    public static void main(String[] args) throws InterruptedException {
        final int threadNum=10;
       ExecutorService pool=Executors.newFixedThreadPool(threadNum);
        pool.execute(new OrderService());
        pool.execute(new MemberService());
        pool.shutdown();
        pool.awaitTermination(1, TimeUnit.HOURS);
        System.out.println("end...");
    }

}

執行結果:

member service....2001
order service....2001
end...




awaitTermination(long timeOut, TimeUnit unit)

當前線程阻塞,直到

  • 等所有已提交的任務(包括正在跑的和隊列中等待的)執行完
  • 或者等超時時間到
  • 或者線程被中斷,拋出InterruptedException

發佈了98 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章