多執行緒案例

fan_rockrock發表於2016-08-05

題目:

        稽核系統有一批工單需要處理,現在啟動三個執行緒進行處理,要求執行緒1處理工單id mod 3 = 1 的工單, 執行緒2處理工單id mod 3 = 2的工單 , 執行緒3處理工單id mod 3 = 0的工單,直到工單全部處理完畢,假設工單有1000個,工單編號從1-1000,工單處理過程簡化為列印工單id即可,要求工單必須按順序處理,即列印結果必須保證從1-1000從小到大遞增。

方法一:

使用Synchronized+Object提供的wait()、notify()、notifyAll()方法

public class 三個執行緒處理1000個工單號 implements Runnable {
    static int num = 1;// 開始的工單號,可以改變
    static final int END = 1000;// 結束工單號
    int id;// 表示執行緒號
    Object o;// 三個執行緒的監視器

    public 三個執行緒處理1000個工單號(int id, Object o) {
        this.id = id;
        this.o = o;
    }

    @Override
    public void run() {
        synchronized (o) {
            while (num <= END) {
                if (num % 3 == id) {// 如果是屬於自己的數,依次列印出來
                    System.out.println(Thread.currentThread().getName() + "正在處理工單號: " + num);
                    ++num;
                    o.notifyAll();
                } else {
                    try {
                        o.wait();
                    } catch (InterruptedException e) {
                        System.out.println("執行緒" + id + "被打斷了");
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Object o = new Object();
        new Thread(new 三個執行緒處理1000個工單號(1, o), "執行緒1").start();
        new Thread(new 三個執行緒處理1000個工單號(2, o), "執行緒2").start();
        new Thread(new 三個執行緒處理1000個工單號(0, o), "執行緒3").start();
    }
}

方法二:使用Lock+Condition提供的await()、signal()、signalAll()

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class 三個執行緒處理1000個工單號 implements Runnable {
    static int num = 1;// 開始的工單號,可以改變
    static final int END = 1000;// 結束工單號
    int id;// 表示執行緒號
    Lock lock;
    Condition condition;

    public 三個執行緒處理1000個工單號(int id, Lock lock, Condition condition) {
        this.id = id;
        this.lock = lock;
        this.condition = condition;
    }

    @Override
    public void run() {
        lock.lock();
        try {
            while (num <= END) {
                if (num % 3 == id) {// 如果是屬於自己的數,依次列印出來
                    System.out.println(Thread.currentThread().getName() + "正在處理工單號: " + num);
                    ++num;
                    condition.signalAll();
                } else {
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        System.out.println("執行緒" + id + "被打斷了");
                    }
                }
            }
        } finally {
            lock.unlock();
        }
    }
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        new Thread(new 三個執行緒處理1000個工單號(1, lock, condition), "執行緒1").start();
        new Thread(new 三個執行緒處理1000個工單號(2, lock, condition), "執行緒2").start();
        new Thread(new 三個執行緒處理1000個工單號(0, lock, condition), "執行緒3").start();
    }
}

執行結果:

執行緒1正在處理工單號: 1
執行緒2正在處理工單號: 2
執行緒3正在處理工單號: 3
執行緒1正在處理工單號: 4
執行緒2正在處理工單號: 5
執行緒3正在處理工單號: 6
執行緒1正在處理工單號: 7
執行緒2正在處理工單號: 8
執行緒3正在處理工單號: 9
執行緒1正在處理工單號: 10
執行緒2正在處理工單號: 11
執行緒3正在處理工單號: 12
執行緒1正在處理工單號: 13
執行緒2正在處理工單號: 14
執行緒3正在處理工單號: 15
執行緒1正在處理工單號: 16
執行緒2正在處理工單號: 17
執行緒3正在處理工單號: 18
執行緒1正在處理工單號: 19
執行緒2正在處理工單號: 20
.........
.........


相關文章