關於多線程兩種方法的思考 賣票問題 同步代碼塊加鎖問題,多線程賣票

來源:互聯網
上載者:User

關於多線程兩種方法的思考 賣票問題 同步代碼塊加鎖問題,多線程賣票

package com.swift.duoxiancheng;class Ticket extends Thread {    Ticket(String name) {        super(name); // 建構函式:設定線程名稱    }    public static int ticket = 1000;    @Override    public void run() {        while (true) {            synchronized ("鎖") {                if (ticket > 0) {                    ticket--;                    System.out.println(Thread.currentThread().getName() + "還有餘票數:" + ticket);                }            }        }    }    public synchronized void sellTickets() {    }}public class ThreadTest_Jicheng {    public static void main(String[] args) {        // 一種是多個線程對應一個對象(如賣票),一種是多個線程對應多個對象(如socket線程)        Ticket t1 = new Ticket("賣票視窗1");        Ticket t2 = new Ticket("賣票視窗2");        Ticket t3 = new Ticket("賣票視窗3");        Ticket t4 = new Ticket("賣票視窗4");        // 上面這種賣票是產生4個對象,每個對象有1000張票要賣出,只是因為線程得到CPU分配有先有後        // 用靜態成員變量共用1000張票,票不在對象的對空間,而在內存方法區,同步問題要解決        t1.start();        t2.start();        t3.start();        t4.start();        System.out.println("Hello World!");    }}

上面是繼承Thread的方法

這種方法較為簡單,只要繼承後複寫run方法即可,缺點是已經繼承別的類就不能在繼承了,有局限性。對單一對象中成員進行操作的多線程需要靜態static關鍵字

下面是實現implements Runnable方法

package com.swift.duoxiancheng;class Tickets implements Runnable {    private int ticket = 1000;    @Override    public void run() {        sell();    }    // 給帶迴圈的方法加synchronized之後只有一個線程賣票,是因為鎖定一個線程執行迴圈當然只有一個線程在賣票,應該把鎖加在迴圈裡邊    // 加在裡邊仍然有線程等待在迴圈外,最後出現負票數的情況,因為while之外也出現了同步,方法中不迴圈賣票,只賣一張票    // while中寫判斷會影響結果,出現負票數    public void sell() {        while (true) {            synchronized (this) {                if (ticket > 0) {                    try {                        Thread.sleep(0);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    ticket--;                    System.out.println(Thread.currentThread().getName() + "還有餘票:" + ticket);                }            }        }    }}public class SellTickets_Runnable {    public static void main(String[] args) {        Tickets t = new Tickets();        Thread t1 = new Thread(t, "票視窗1");        Thread t2 = new Thread(t, "票視窗2");        Thread t3 = new Thread(t, "票視窗3");        Thread t4 = new Thread(t, "票視窗4");        t1.start();        t2.start();        t3.start();        t4.start();        System.out.println("Hello World!");    }}

鎖可以在方法上,也可以用同步代碼塊,同步代碼塊較好,可以局部鎖

鎖可以使對象synchronized(this) 也可以是字串synchronized("鎖")

加鎖的時候注意,如果鎖住的是一個迴圈,那就只有一個線程執行直到完成

package com.swift.duoxiancheng;class Ticketz implements Runnable {    private int ticket = 100;    @Override    public void run() {        sell();    }    //加上synchronized之後只有一個線程賣票,鎖定一個線程執行迴圈當然只有一個線程在賣票    public synchronized void sell() {        while (ticket > 0) {            try {                Thread.sleep(5);            } catch (InterruptedException e) {                e.printStackTrace();            }            ticket--;            System.out.println(Thread.currentThread().getName() + "還有餘票:" + ticket);        }    }}public class SellTickets_OnlyOneThreadSell {    public static void main(String[] args) {        Ticketz t = new Ticketz();        Thread t1 = new Thread(t, "票視窗1");        Thread t2 = new Thread(t, "票視窗2");        Thread t3 = new Thread(t, "票視窗3");        Thread t4 = new Thread(t, "票視窗4");        t1.start();        t2.start();        t3.start();        t4.start();        System.out.println("Hello World!");    }}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.