線程入門——終結任務

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by Administrator on 2017/10/11.
 */
class Count {
    private int count = 0;
    private Random rand = new Random(47);

    //remove the synchronized keyword to see counting faild
    public synchronized int increment() {
        int temp = count;
        System.out.print("count: " + count);
        //nextBoolean用於從該隨機數生成器的序列獲得下一個僞均勻分佈的布爾值。
        //yield half the time
        if (rand.nextBoolean())
            Thread.yield();
        return (count = ++temp);
    }

    public synchronized int value() {
        return count;
    }
}

class Entrance implements Runnable {
    private static Count count = new Count();
    private static List<Entrance> entrances = new ArrayList<Entrance>();
    private int number = 0;
    //doesn't need synchronization to read
    private int id;
    private static volatile boolean canceled = false;

    //atomic operation on a volatile field:
    public static void cancel() {
        canceled = true;
    }

    public Entrance(int id) {
        this.id = id;
        //keep this task in a list. Also prevents
        //garbage collection of dead tasks
        entrances.add(this);
    }

    public void run() {
        while (!canceled) {
            synchronized (this) {
                ++number;
            }
            System.out.println(this + " Total: " + count.increment());
            try {
                TimeUnit.MICROSECONDS.sleep(100);
            } catch (InterruptedException e) {
                System.out.print("sleep interrupted");
            }
        }
        System.out.print("Stopping " + this + "\n");
    }

    public synchronized int getValue() {
        return number;
    }

    public String toString() {
        return "Entrance " + id + ": " + getValue() + " ";
    }

    public static int getTotalCount() {
        return count.value();
    }

    public static int sumEntrances() {
        int sum = 0;
        for (Entrance entrance : entrances) {
            sum += entrance.getValue();
        }
        return sum;
    }
}

public class OrnamentalGarden {
    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            exec.execute(new Entrance(i));
        }
        //Run for a while ,then stop and collect the data:
        TimeUnit.SECONDS.sleep(1);
        Entrance.cancel();
        exec.shutdown();
        if (!exec.awaitTermination(250, TimeUnit.MICROSECONDS))
            System.out.print("Some tasks were not terminated!");

        System.out.print("\nTotal: " + Entrance.getTotalCount());
        System.out.print("\nSum of Entrances: " + Entrance.sumEntrances());
    }
}

 

count: 0Entrance 2: 1  Total: 1
count: 1Entrance 4: 1  Total: 2
count: 2Entrance 3: 1  Total: 3
count: 3Entrance 1: 1  Total: 4
count: 4Entrance 0: 1  Total: 5
count: 5Entrance 2: 2  Total: 6
count: 6Entrance 3: 2  Total: 7
count: 7Entrance 0: 2  Total: 8
count: 8Entrance 1: 2  Total: 9
count: 9Entrance 4: 2  Total: 10
count: 10Entrance 1: 3  Total: 11
count: 11Entrance 0: 3  Total: 12
count: 12Entrance 4: 3  Total: 13
count: 13Entrance 2: 3  Total: 14
count: 14Entrance 3: 3  Total: 15
count: 15Entrance 1: 4  Total: 16
count: 16Entrance 3: 4  Total: 17
count: 17Entrance 2: 4  Total: 18
count: 18Entrance 4: 4  Total: 19
count: 19Entrance 0: 4  Total: 20
count: 20count: 21Entrance 3: 5  Total: 22
Entrance 2: 5  Total: 21
count: 22Entrance 4: 5  Total: 23
count: 23Entrance 0: 5  Total: 24
count: 24Entrance 1: 5  Total: 25
count: 25Entrance 3: 6  Total: 26
count: 26Entrance 0: 6  Total: 27
count: 27Entrance 4: 6  Total: 28
count: 28Entrance 2: 6  Total: 29
count: 29Entrance 1: 6  Total: 30
count: 30Entrance 3: 7  Total: 31
count: 31Entrance 4: 7  Total: 32
count: 32Entrance 2: 7  Total: 33
count: 33Entrance 1: 7  Total: 34
count: 34Entrance 0: 7  Total: 35
count: 35Entrance 2: 8  Total: 36
count: 36Entrance 4: 8  Total: 37
count: 37Entrance 0: 8  Total: 38
count: 38Entrance 1: 8  Total: 39
count: 39Entrance 3: 8  Total: 40
count: 40Entrance 3: 9  Total: 41
count: 41Entrance 4: 9  Total: 42
count: 42Entrance 0: 9  Total: 43
count: 43Entrance 1: 9  Total: 44
count: 44Entrance 2: 9  Total: 45
count: 45Entrance 4: 10  Total: 46
count: 46Entrance 3: 10  Total: 47
count: 47Entrance 1: 10  Total: 48
count: 48Entrance 0: 10  Total: 49
count: 49Entrance 2: 10  Total: 50
count: 50count: 51Entrance 2: 11  Total: 51
Entrance 4: 11  Total: 52
count: 52Entrance 1: 11  Total: 53
count: 53Entrance 0: 11  Total: 54
count: 54Entrance 3: 11  Total: 55
count: 55Entrance 3: 12  Total: 56
count: 56Entrance 4: 12  Total: 57
count: 57Entrance 2: 12  Total: 58
count: 58Entrance 1: 12  Total: 59
count: 59Entrance 0: 12  Total: 60
count: 60Entrance 4: 13  Total: 61
count: 61Entrance 0: 13  Total: 62
count: 62Entrance 1: 13  Total: 63
count: 63Entrance 2: 13  Total: 64
count: 64Entrance 3: 13  Total: 65
count: 65Entrance 1: 14  Total: 66
count: 66Entrance 2: 14  Total: 67
count: 67Entrance 4: 14  Total: 68
count: 68Entrance 3: 14  Total: 69
count: 69Entrance 0: 14  Total: 70
count: 70Entrance 1: 15  Total: 71
count: 71Entrance 0: 15  Total: 72
count: 72Entrance 3: 15  Total: 73
count: 73Entrance 2: 15  Total: 74java

。。。。。。dom

count: 4817Entrance 0: 962  Total: 4818
Entrance 4: 966  Total: 4815
count: 4818Entrance 1: 967  Total: 4819
Stopping Entrance 2: 958 
Stopping Entrance 1: 967 
Stopping Entrance 0: 962 
Stopping Entrance 4: 966 
Stopping Entrance 3: 966 this

Total: 4819
Sum of Entrances: 4819
Process finished with exit code 0atom

場景:一個花園,N個門,統計天天經過每一個門口進入的參觀者。設計

設計:經過使用單個的Count對象來跟蹤花園參觀者的主計數值,而且將其看成Entrance類中的一個靜態域進行存儲。code

Count.increment()和Count.value()都是synchronized的,用來控制對count域的訪問。increment()方法使用了Random對象,目的是在從把count讀取到temp中,到遞增temp並將其存儲回count的這段時間裏,有大約一半的時間產生讓步。若是你將increment()上的synchronized關鍵字註釋掉,那麼這個程序就會崩潰,由於多個任務將同時訪問並修改count(yield()會使問題更快地發生)對象

number是Entrance任務裏維護的,它包含經過某個特定入口進行的參觀者的數量。這提供了對count對象的雙重檢查,以確保其記錄的參觀者數量是正確的。Entrance.run()只是遞增number和count對象,而後休眠100ms.rem

相關文章
相關標籤/搜索