Java多線(xiàn)程--線(xiàn)程同步

線(xiàn)程的同步是為了防止多個(gè)線(xiàn)程訪問(wèn)一個(gè)數(shù)據(jù)對(duì)象時(shí),對(duì)數(shù)據(jù)造成的破壞。同步的方法通過(guò)鎖來(lái)實(shí)現(xiàn),每個(gè)對(duì)象都有且僅有一個(gè)鎖,這個(gè)鎖與一個(gè)特定的對(duì)象關(guān)聯(lián),線(xiàn)程一旦獲取了對(duì)象鎖,其他訪問(wèn)該對(duì)象的線(xiàn)程就無(wú)法再訪問(wèn)該對(duì)象的其他同步方法。
對(duì)于同步的方法,這里先主要學(xué)習(xí)使用synchronized關(guān)鍵字修飾的方法和鎖對(duì)象Lock
1、 Synchronized
Java中每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖,當(dāng)程序運(yùn)行到非靜態(tài)的synchronized同步方法上時(shí),自動(dòng)獲得與正在執(zhí)行代碼類(lèi)的當(dāng)前實(shí)例(this實(shí)例)有關(guān)的鎖,也只有在這時(shí),對(duì)象鎖才起作用。一個(gè)對(duì)象只有一個(gè)鎖。如果一個(gè)線(xiàn)程獲得該鎖,就沒(méi)有其他線(xiàn)程可以獲得鎖,直到第一個(gè)線(xiàn)程釋放(或返回)鎖。也就是說(shuō)任何其他線(xiàn)程都不能進(jìn)入該對(duì)象上的synchronized方法或代碼塊,直到持鎖線(xiàn)程退出了synchronized同步方法或代碼塊該鎖被釋放。(同步只能是同步方法,變量和類(lèi)不能同步)

package Synchronized20170412;

/**
 * 線(xiàn)程同步的運(yùn)用
 */
public class Synchronized20170412 {
    public static void main(String[] args) {  
        Fun f = new Fun();
        NewThread new_thread = new NewThread(f);
        Thread thread1 = new Thread(new_thread);
        thread1.start();
        Thread thread2 = new Thread(new_thread);
        thread2.start();
    }

}

class Fun {
    private int total = 0;
    public int getTotal() {
        return total;
    }

    /**
     * 用同步方法實(shí)現(xiàn)
     * 
     * @param money
     */
    public synchronized void add(int i) {
        total += i;
    }

    /**
     * 用同步代碼塊實(shí)現(xiàn)
     * 
     * @param money
     */
    public void add1(int i) {
        synchronized (this) {
            total += i;
        }
    }
}

class NewThread implements Runnable {
    private Fun f;

    public NewThread(Fun f) {
        this.f = f;
    }

    public void run() {
        //System.out.println(Thread.currentThread().getName() + " Total = " + f.getTotal());
        for (int i = 0; i < 5; i++) {
            f.add1(10);
            //f.add(10);
            System.out.println(Thread.currentThread().getName() + " i = " + i + " Total = " + f.getTotal());
        }
    }
}

結(jié)果如下:


Paste_Image.png

可以看到線(xiàn)程0和線(xiàn)程1之間只有等待對(duì)方釋放鎖后,自己才能獲得鎖并在Total上加10,他們之間的操作不會(huì)有沖突.

2、 Lock
Lock是java.util.concurrent.locks包下的接口,Lock 實(shí)現(xiàn)提供了比使用synchronized 方法和語(yǔ)句可獲得的更廣泛的鎖定操作
與synchronized的區(qū)別:
Lock可以使用Condition進(jìn)行線(xiàn)程之間的調(diào)度,Synchronized則使用Object對(duì)象本身的notify, wait, notityAll調(diào)度機(jī)制。
Condition(即對(duì)象監(jiān)視器)是Java5以后出現(xiàn)的機(jī)制,它有更好的靈活性,在一個(gè)對(duì)象里面可以有多個(gè)Condition,則線(xiàn)程可以注冊(cè)在不同的Condition,從而可以有選擇性的調(diào)度線(xiàn)程,更加靈活。他并不是一種替代內(nèi)置加鎖的方法,而是當(dāng)內(nèi)置加鎖機(jī)制不適用時(shí),作為一種可選擇的高級(jí)功能,lock接口提供了一種無(wú)條件的、可輪詢(xún)的、定時(shí)的以及可中斷的鎖獲取機(jī)制,所有的加鎖和解鎖方法都是顯示的
Synchronized就相當(dāng)于整個(gè)對(duì)象只有一個(gè)單一的Condition(即該對(duì)象本身)所有的線(xiàn)程都注冊(cè)在它身上

package Lock20170412;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Lock20170412 {  
    public static void main(String[] args) {  
        Fun f = new Fun();
        NewThread new_thread = new NewThread(f);
        Thread thread1 = new Thread(new_thread);
        thread1.start();
        Thread thread2 = new Thread(new_thread);
        thread2.start(); 
    }  
}  


class Fun {
    private int total = 0;
    public int getTotal() {
        return total;
    }

    public void add(int i) {
        total += i;
    }
}

class NewThread implements Runnable {
    private Fun f;
    private Lock lock = new ReentrantLock();// 鎖對(duì)象 

    public NewThread(Fun f) {
        this.f = f;
    }

    public void run() {
        lock.lock();// 得到鎖 
        try {
            for (int i = 0; i < 5; i++) {
                f.add(10);
                System.out.println(Thread.currentThread().getName() + " i = " + i + " Total = " + f.getTotal());
            }
        } finally {  
            lock.unlock();// 釋放鎖  
        }  
    }
}  

結(jié)果如下:


Paste_Image.png

可以看到線(xiàn)程0執(zhí)行完畢后才釋放鎖,線(xiàn)程1得到鎖后才開(kāi)始執(zhí)行

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容