1. 程式人生 > >多執行緒的資料共享

多執行緒的資料共享

通過Runnable介面實現資料共享

下面通過模擬售票系統的一個小demo展示資料共享情況:

1.首先是一個實現了runnable介面的類,此類的成員變數票數ticketNum作為共享資料,因是成員變數,私有,所以此類不能new多個,只得通過new不同的Thread執行緒共用這一個物件。

/**
 * @author cuijiao TicketSys只能new一次,多個執行緒來用它,共享它的成員變數資料
 */
public class TicketSys implements Runnable {
    private int ticketNum = 10;// 成員變數

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (ticketNum > 0) {
            // 1.收錢
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // 2.售票
            System.out.println(Thread.currentThread().getName() + "sell ticket" + ticketNum);
            // 3.票數減少
            ticketNum--;
        }
    }

}

2.多個執行緒模擬售票視窗

/**
 * @author cuijiao
 *
 */
public class Demo1 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        TicketSys tc = new TicketSys();// 票務系統,只能new一次
        Thread th1 = new Thread(tc, "視窗1");// 視窗1
        Thread th2 = new Thread(tc, "視窗2");// 視窗2
        Thread th3 = new Thread(tc, "視窗3");// 視窗3
        th1.start();
        th2.start();
        th3.start();
    }

}

其中的某次執行結果如下:

接下來用CPU時間片排程分別對出現三次ticket=4和出現ticket=0,-1解釋:

通過繼承 Thread實現資料共享

主要利用內部類可訪問外部類成員,使用內部類實現,執行結果及原因與上同,不贅述,僅貼出程式碼:

/**
 * @author cuijiao
 *
 *         內部類:只想在當前類使用,其他地方用不到的情況下 使用內部類,可以訪問外部類的成員變數
 */
public class TicketSys {
    private int ticketNum = 10;// 成員變數

    private class Window extends Thread {
        public Window(String name) {
            super(name);
        }

        @Override
        public void run() {
            // TODO Auto-generated method stub
            while (ticketNum > 0) {
                // 1.收錢
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 2.售票
                System.out.println(Thread.currentThread().getName() + "sell ticket" + ticketNum);
                // 3.票數減少
                ticketNum--;
            }
        }

    }

    /**
     * 建立並啟動執行緒
     *
     * @param name
     */
    public void openWindow(String name) {
        new Window(name).start();
    }
}

呼叫:

public class Demo1 {

 
    public static void main(String[] args) {
        TicketSys tc = new TicketSys();// 票務系統,只能new一次
        tc.openWindow("視窗1");// 每呼叫一次openWindow方法建立並啟動一個新的執行緒
        tc.openWindow("視窗2");
        tc.openWindow("視窗3");
    }

}