1. 程式人生 > >synchronized同步的實現——多執行緒購票

synchronized同步的實現——多執行緒購票

同步的由來

當兩個或兩個以上的執行緒需要共享資源,必須使用某種方法來確定資源在某一時刻僅被一個執行緒佔用,達到此目的的過程叫做同步。(synchronized)

同步的實現

方法級同步(method-level synchronized)
synchronized void method( ) {
//同步的方法
}
物件級同步( block-level synchronized )
synchronized ( object ) {
//要同步的語句
}

應用場景舉例——多執行緒購票(同步方法)

package com.foot.lesson03;

public
class TestSynchronized { public static void main(String[] args) { Tickets ticket = new Tickets(); BuyerThread bta = new BuyerThread(ticket); bta.setName("售票點A"); BuyerThread btb = new BuyerThread(ticket); btb.setName("售票點B"); bta.start(); btb.start(); } } class
Tickets {
private int count; public Tickets() { this.count = 10; } // 購票操作 public synchronized String sell(String name) { if (this.count > 0) { count--; return name + "購票成功,剩餘:" + count; } return "票已經售完!"; } } class BuyerThread
extends Thread {
private Tickets ticket = null; public BuyerThread(Tickets ticket) { this.ticket = ticket; } @Override public void run() { while (true) { String res = ticket.sell(getName()); System.out.println(res); try { sleep(1); } catch (Exception e) { e.printStackTrace(); } } } }

應用場景舉例——多執行緒購票(同步物件推薦使用)

package com.foot.lesson03;

public class TestSynchronized {

    public static void main(String[] args) {
        Tickets ticket = new Tickets();
        BuyerThread bta = new BuyerThread(ticket);
        bta.setName("售票點A");
        BuyerThread btb = new BuyerThread(ticket);
        btb.setName("售票點B");
        bta.start();
        btb.start();
    }

}

class Tickets {
    private Integer count;

    public Tickets() {
        this.count = 10;
    }

    // 購票操作
    public String sell(String name) {
        synchronized(this.count) {
            if(this.count > 0) {
                count--;
                return name + "購票成功,剩餘:" + count;
            } else {
                return "票已經售完!";
            }
        }
    }
}

class BuyerThread extends Thread {
    private Tickets ticket = null;

    public BuyerThread(Tickets ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (true) {
            String res = ticket.sell(getName());
            System.out.println(res);
            try {
                sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

執行結果如下

售票點B購票成功,剩餘:8
售票點A購票成功,剩餘:9
售票點A購票成功,剩餘:7
售票點B購票成功,剩餘:6
售票點A購票成功,剩餘:5
售票點B購票成功,剩餘:4
售票點B購票成功,剩餘:3
售票點A購票成功,剩餘:2
售票點B購票成功,剩餘:1
售票點A購票成功,剩餘:0
票已經售完!
票已經售完!

該執行結果,體現了多執行緒優先順序相同的情況產生的效果,取決於內部時間片的排程。

多執行緒購票修改

package com.foot.lesson4;

public class TestSynchronized {

    public static void main(String[] args) {
        Tickets ticket = new Tickets();
        BuyerThread bt = null;
        String[] str = {"A", "B", "C", "D", "E", "F"};
        for (String string : str) {//多個地點同時購票
            bt = new BuyerThread(ticket);
            bt.setName("售票點" + string);
            bt.start();
        }


        BuyerThread bta = new BuyerThread(ticket);
        bta.setName("售票點1");
        bta.start();
    }

}

class Tickets {
    private Integer count;

    public Tickets() {
        this.count = 100;
    }

    // 購票操作
    public String sell(String name) {
        synchronized(this.count) {
            if(this.count > 0) {
                count--;
                return name + "購票成功,剩餘:" + count;
            } else {
                return null;
            }
        }
    }
}

class BuyerThread extends Thread {
    private Tickets ticket = null;

    public BuyerThread(Tickets ticket) {
        this.ticket = ticket;
    }

    @Override
    public void run() {
        while (true) {
            String res = ticket.sell(getName());
            if(null != res) {
                System.out.println(res);
            } else {
                System.out.println("票已售完!");
                break;  //用於退出該執行緒
            }
            try {
                sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

結果

體現了執行緒執行時是受時間片控制的。
售票點B購票成功,剩餘:98
售票點1購票成功,剩餘:93
售票點F購票成功,剩餘:94
售票點C購票成功,剩餘:97
售票點D購票成功,剩餘:96
售票點E購票成功,剩餘:95
售票點A購票成功,剩餘:99
售票點B購票成功,剩餘:92
售票點1購票成功,剩餘:91
售票點D購票成功,剩餘:90
售票點F購票成功,剩餘:86
售票點C購票成功,剩餘:87
售票點A購票成功,剩餘:88
售票點E購票成功,剩餘:89
售票點B購票成功,剩餘:85
售票點C購票成功,剩餘:83
售票點1購票成功,剩餘:84
售票點D購票成功,剩餘:82
售票點A購票成功,剩餘:79
售票點E購票成功,剩餘:81
售票點F購票成功,剩餘:80
售票點A購票成功,剩餘:78
售票點1購票成功,剩餘:77
售票點B購票成功,剩餘:72
售票點F購票成功,剩餘:73
售票點C購票成功,剩餘:75
售票點D購票成功,剩餘:76
售票點E購票成功,剩餘:74
售票點C購票成功,剩餘:70
售票點1購票成功,剩餘:65
售票點F購票成功,剩餘:67
售票點B購票成功,剩餘:66
售票點E購票成功,剩餘:68
售票點A購票成功,剩餘:69
售票點D購票成功,剩餘:69
售票點B購票成功,剩餘:64
售票點D購票成功,剩餘:58
售票點A購票成功,剩餘:60
售票點E購票成功,剩餘:63
售票點C購票成功,剩餘:59
售票點F購票成功,剩餘:60
售票點1購票成功,剩餘:62
售票點B購票成功,剩餘:57
售票點1購票成功,剩餘:56
售票點D購票成功,剩餘:54
售票點F購票成功,剩餘:55
售票點E購票成功,剩餘:51
售票點C購票成功,剩餘:52
售票點A購票成功,剩餘:53
售票點B購票成功,剩餘:50
售票點F購票成功,剩餘:47
售票點1購票成功,剩餘:46
售票點D購票成功,剩餘:45
售票點E購票成功,剩餘:47
售票點C購票成功,剩餘:49
售票點A購票成功,剩餘:47
售票點B購票成功,剩餘:43
售票點A購票成功,剩餘:40
售票點F購票成功,剩餘:39
售票點1購票成功,剩餘:41
售票點E購票成功,剩餘:42
售票點C購票成功,剩餘:44
售票點D購票成功,剩餘:38
售票點A購票成功,剩餘:37
售票點1購票成功,剩餘:35
售票點B購票成功,剩餘:36
售票點F購票成功,剩餘:34
售票點C購票成功,剩餘:33
售票點E購票成功,剩餘:31
售票點D購票成功,剩餘:32
售票點B購票成功,剩餘:30
售票點F購票成功,剩餘:27
售票點C購票成功,剩餘:28
售票點1購票成功,剩餘:29
售票點E購票成功,剩餘:26
售票點A購票成功,剩餘:25
售票點D購票成功,剩餘:24
售票點F購票成功,剩餘:23
售票點A購票成功,剩餘:22
售票點1購票成功,剩餘:21
售票點B購票成功,剩餘:20
售票點C購票成功,剩餘:19
售票點D購票成功,剩餘:18
售票點E購票成功,剩餘:17
售票點A購票成功,剩餘:16
售票點1購票成功,剩餘:14
售票點F購票成功,剩餘:13
售票點B購票成功,剩餘:15
售票點E購票成功,剩餘:10
售票點C購票成功,剩餘:11
售票點D購票成功,剩餘:12
售票點E購票成功,剩餘:9
售票點B購票成功,剩餘:4
售票點D購票成功,剩餘:3
售票點C購票成功,剩餘:5
售票點1購票成功,剩餘:6
售票點A購票成功,剩餘:7
售票點F購票成功,剩餘:8
售票點B購票成功,剩餘:2
票已售完!
票已售完!
票已售完!
售票點D購票成功,剩餘:1
售票點C購票成功,剩餘:0
票已售完!
票已售完!
票已售完!
票已售完!