天天看點

多線程學習 synchronized加鎖 保持資料一緻 四

java中任何對象預設都會有一個互斥鎖标記,用來配置設定給線程。也可以選擇這個所标記 沒有配置設定給任何線程/或者隻能給一個線程。 隻有拿到對象所标記的線程才能進入到對該對象加鎖的同步代碼塊。 同步鎖的是對象 線程退出同步代碼塊(線程執行完畢 确切來說,run方法執行完畢),會釋放相應的鎖标記。

synchronized 修飾代碼塊 對象鎖标記 上代碼

package com.baigu.demo1.stack;

public class TestStack {
    public static void main(String[] args) throws InterruptedException {
        Stack stack = new Stack();
//        stack.print();
//        stack.posh('C');
//        stack.print();
//        stack.pop();
//        stack.print();

        PushThread t1 = new PushThread(stack);
        PopThread t2 = new PopThread(stack);

        stack.print();
        System.out.println();
        t1.start();
        t2.start();
        Thread.sleep(1000); //睡一秒讓t1 t2線程執行結束在執行主線程
        stack.print();
    }
}

class Stack{
    private char[] data={'A','B',' ',' ',' ',' ',' ',' '};
    private int index=2;    //記錄數組中有效元素的個數

    public void posh(char c){
        System.out.println(c+"  poshed! 入棧");
        data[index]=c;
        try {
            Thread.sleep(1000);        //睡0.1秒類似于時間片到期
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        index++;
    }

    public void  pop(){
        index --;
        System.out.println(data[index]+"  poped!  出棧");
        data[index]=' ';
    }

    public void print(){
        for (char s:data)
            System.out.print(s);
    }
}

class PushThread extends Thread{
    Stack s;
    public PushThread(Stack s) {
        this.s = s;
    }

    @Override
    public void run() {
//        s.posh('C');
        synchronized (s){       //同步代碼塊     參數為對象的引用        對象鎖标記
            s.posh('C');
        }
    }
}
class PopThread extends Thread{
    Stack s;

    public PopThread(Stack s) {
        this.s = s;
    }
    @Override
    public void run() {
        synchronized (s){       //同步代碼塊     參數為對象的引用    對象鎖标記
            s.pop();
        }
    }
}
           

synchronized 修飾方法 方法鎖标記 上代碼

package com.baigu.demo1.stack;

public class Testsynchronizedmethod {
    public static void main(String[] args) throws InterruptedException {
        StackTwo stack = new StackTwo();
        PushThreadTwo t1 = new PushThreadTwo(stack);
        PopThreadTwo t2 = new PopThreadTwo(stack);

        stack.print();
        System.out.println();
        t1.start();
        t2.start();
        Thread.sleep(1000); //睡一秒讓t1 t2線程執行結束在執行主線程
        stack.print();
    }
}

class StackTwo{
    private char[] data={'A','B',' ',' ',' ',' ',' ',' '};
    private int index=2;    //記錄數組中有效元素的個數

    public synchronized void posh(char c){      //方法鎖标記
        System.out.println(c+"  poshed! 入棧");
        data[index]=c;
        try {
            Thread.sleep(800);        //睡0.1秒類似于時間片到期
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        index++;
    }

    public synchronized void  pop(){         //方法鎖标記
        index --;
        System.out.println(data[index]+"  poped!  出棧");
        data[index]=' ';
    }

    public void print(){
        for (char s:data)
            System.out.print(s);
    }
}

class PushThreadTwo extends Thread{
    StackTwo s;
    public PushThreadTwo(StackTwo s) {
        this.s = s;
    }

    @Override
    public void run() {
            s.posh('C');
    }
}

class PopThreadTwo extends Thread{
    StackTwo s;

    public PopThreadTwo(StackTwo s) {
        this.s = s;
    }
    @Override
    public void run() {
            s.pop();
    }
}

           

synchronized鎖機制 無論是同步代碼塊還是作為修飾符 兩種本質相同

下面是做的一些總結

線程同步:
當多線程并發通路臨界資源(同一個對象)時,多線程同時通路同一個對象時,如果破壞了
原子操作(不可分割的操作),就會造成資料不一緻。和資料庫中的事務類似。

1.synchronized(o){}: 對對象o加鎖的同步代碼塊  同步代碼塊保護原子操作不被破壞。

個人了解:主線程運作優于自己建立的線程運作。

java中任何對象預設都會有一個互斥鎖标記,用來配置設定給線程。也可以選擇這個所标記
沒有配置設定給任何線程/或者隻能給一個線程。

隻有拿到對象所标記的線程才能進入到對該對象加鎖的同步代碼塊。
同步鎖的是對象
線程退出同步代碼塊(線程執行完畢 真正意義上,run方法結束),會釋放相應的鎖标記。

2.synchronized(用作方法修飾符),synchronized修飾的方法叫做同步方法  
同步方法指的是在整個方法的範圍内對目前對象加鎖。
隻有拿到對象所标記的線程才能調用該對象的同步方法。

同步方法等同于同步代碼塊。

鎖池:任何對象都有的一個空間,用來存放等待該對象鎖标記的線程 (一個或多個)
利用鎖機制解決線程的同步問題,隻有拿到對象所标記的線程才能進入到對該對象加鎖的
同步代碼塊(原子操作)。
           

線程架構圖

多線程學習 synchronized加鎖 保持資料一緻 四

糾正一點,較之前說的五中狀态,現在又增加了一種 鎖池狀态。

這輩子堅持與不堅持都不可怕,怕的是獨自走在堅持的道路上。 歡迎加入技術群聊。

多線程學習 synchronized加鎖 保持資料一緻 四

繼續閱讀