1. 程式人生 > >線程池基礎一

線程池基礎一

程序 bsp exce static seconds code interrupt edt 進行

技術分享

我們來看下面程序的代碼:經典的生產者消費者來實現

package com.bjsxt.height.design016;

public final class Data {

    private String id;
    private String name;
    
    public Data(String id, String name){
        this.id = id;
        this.name = name;
    }
    
    public String getId() {
        return id;
    }

    
public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString(){ return "{id: " + id + ", name: " + name + "}"; } }

package com.bjsxt.height.design016;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class Provider implements Runnable{
    
    //共享緩存區
    private BlockingQueue<Data> queue;
    
//多線程間是否啟動變量,有強制從主內存中刷新的功能。即時返回線程的狀態 private volatile boolean isRunning = true; //id生成器 private static AtomicInteger count = new AtomicInteger(); //隨機對象 private static Random r = new Random(); public Provider(BlockingQueue queue){ this.queue = queue; } @Override public void run() { while(isRunning){ try { //隨機休眠0 - 1000 毫秒 表示獲取數據(產生數據的耗時) Thread.sleep(r.nextInt(1000)); //獲取的數據進行累計... int id = count.incrementAndGet(); //比如通過一個getData方法獲取了 Data data = new Data(Integer.toString(id), "數據" + id); System.out.println("當前線程:" + Thread.currentThread().getName() + ", 獲取了數據,id為:" + id + ", 進行裝載到公共緩沖區中..."); if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){ System.out.println("提交緩沖區數據失敗...."); //do something... 比如重新提交 } } catch (InterruptedException e) { e.printStackTrace(); } } } public void stop(){ this.isRunning = false; } }

package com.bjsxt.height.design016;

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class Consumer implements Runnable{

    private BlockingQueue<Data> queue;
    
    public Consumer(BlockingQueue queue){
        this.queue = queue;
    }
    
    //隨機對象
    private static Random r = new Random(); 

    @Override
    public void run() {
        while(true){
            try {
                //獲取數據
                Data data = this.queue.take();
                //進行數據處理。休眠0 - 1000毫秒模擬耗時
                Thread.sleep(r.nextInt(1000));
                System.out.println("當前消費線程:" + Thread.currentThread().getName() + ", 消費成功,消費數據為id: " + data.getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

package com.bjsxt.height.design016;

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

public class Main {

    public static void main(String[] args) throws Exception {
        //內存緩沖區
        BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>(10);
        //生產者
        Provider p1 = new Provider(queue);
        
        Provider p2 = new Provider(queue);
        Provider p3 = new Provider(queue);
        //消費者
        Consumer c1 = new Consumer(queue);
        Consumer c2 = new Consumer(queue);
        Consumer c3 = new Consumer(queue);
        //創建線程池運行,這是一個緩存的線程池,可以創建無窮大的線程,沒有任務的時候不創建線程。空閑線程存活時間為60s(默認值)

        ExecutorService cachePool = Executors.newCachedThreadPool();
        cachePool.execute(p1);
        cachePool.execute(p2);
        cachePool.execute(p3);
        cachePool.execute(c1);
        cachePool.execute(c2);
        cachePool.execute(c3);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        p1.stop();
        p2.stop();
        p3.stop();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        
//        cachePool.shutdown(); 
//        cachePool.shutdownNow();
        

    }
    
}

程序的運行結果是:

當前線程:pool-1-thread-2, 獲取了數據,id為:1, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:2, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-3, 獲取了數據,id為:3, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-2, 獲取了數據,id為:4, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 3
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 1
當前線程:pool-1-thread-3, 獲取了數據,id為:5, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-3, 獲取了數據,id為:6, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:7, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 5
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 2
當前線程:pool-1-thread-2, 獲取了數據,id為:8, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 4
當前線程:pool-1-thread-3, 獲取了數據,id為:9, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 7
當前線程:pool-1-thread-3, 獲取了數據,id為:10, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 8
當前線程:pool-1-thread-1, 獲取了數據,id為:11, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:12, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-2, 獲取了數據,id為:13, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 6
當前線程:pool-1-thread-3, 獲取了數據,id為:14, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 9
當前線程:pool-1-thread-2, 獲取了數據,id為:15, 進行裝載到公共緩沖區中...
當前線程:pool-1-thread-1, 獲取了數據,id為:16, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 12
當前線程:pool-1-thread-3, 獲取了數據,id為:17, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 10
當前線程:pool-1-thread-2, 獲取了數據,id為:18, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 11
當前線程:pool-1-thread-1, 獲取了數據,id為:19, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 13
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 16
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 15
當前線程:pool-1-thread-3, 獲取了數據,id為:20, 進行裝載到公共緩沖區中...
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 17
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 14
當前消費線程:pool-1-thread-4, 消費成功,消費數據為id: 18
當前消費線程:pool-1-thread-5, 消費成功,消費數據為id: 19
當前消費線程:pool-1-thread-6, 消費成功,消費數據為id: 20

相當的經典

線程池基礎一