1. 程式人生 > 其它 >多執行緒(二)

多執行緒(二)

執行緒同步

還是那個經典問題賣票
一。各自單執行緒賣自己的票

public class CellTicket {
    public static void main(String[] args) {
        Windows w1= new Windows();
        Windows w2= new Windows();
        Windows w3= new Windows();
        w1.start();
        w2.start();
        w3.start();
    }
}
class Windows extends Thread
{ private Integer ticket=100; @Override public void run() { while (ticket>0){ System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票"); ticket--; } } }

二。多執行緒操作公共的100張票,實現runnable介面的方式實現多執行緒,在run方法中使用sleep方法,出現售賣負數的票的情況

public class CellTicket {
    public static void main(String[] args) {
        myRunnables resource= new myRunnables();
        Thread w1=new Thread(resource);
        Thread w2=new Thread(resource);
        Thread w3=new Thread(resource);
        w1.start();
        w2.start();
        w3.start();
} } class myRunnables implements Runnable{ private Integer ticket=100; public void run() { while (ticket>0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票"); ticket--; } } }

以上兩個問題是我們學習多執行緒中太常見的情況了,說下下面的情況
一)使用繼承Thread的方式怎麼實現售賣同一個資源的票數,方法將共享資源加上上static關鍵字

class Windowss extends Thread{
//加static
    private static Integer ticket=100;

    public void run() {
        while (ticket>0){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"賣出第"+ticket+"張票");
            ticket--;
        }
    }
}

在這裡插入圖片描述
出現負票是因為,多個執行緒同時拿到了同一張票,這個問題的解決就需要我們用到synchronized(同步)

synchronized關鍵字

synchronized關鍵字修飾程式碼塊或者方法,稱為同步程式碼塊和同步方法

class myRunnables implements Runnable {
    private Integer ticket = 100;
    Object o=new Object();

    public void run() {
        while (true) {
            synchronized (o) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "賣出第" + ticket + "張票");
                    ticket--;
                }

            }
        }

    }
}

解決了賣重票和賣負數的情況
在這裡插入圖片描述
使用synchronized關鍵字修飾程式碼塊需要一個同步鎖:上面程式碼中用到的同步鎖,就是我new的Object物件。
同步鎖需要具有以下特徵才能實現同步效果:
①可以是任意物件,注意任意的都可以
②該同步鎖物件必須是唯一的,多個執行緒必須使用同一個同步鎖物件。當由程序執行方法時,獲取同步鎖,只有取得鎖才能執行邏輯。沒有取得就要等待。