Java多線程鎖如何進(jìn)行數(shù)據(jù)同步共享
Java多線程鎖是為了解決數(shù)據(jù)同步中的數(shù)據(jù)安全問題,下面我們就來(lái)詳細(xì)的學(xué)習(xí)下有關(guān)于Java多線程鎖的相關(guān)問題。只有不斷的學(xué)習(xí)才能不斷的提高自身的相關(guān)技術(shù)。
大多數(shù)應(yīng)用程序要求線程互相通信來(lái)同步它們的動(dòng)作。在Java程序中最簡(jiǎn)單實(shí)現(xiàn)同步的方法就是上Java多線程鎖。為了防止同時(shí)訪問共享資源,線程在使用資源的前后可以給該資源上鎖和開鎖。假想給復(fù)印機(jī)上鎖,任一時(shí)刻只有一個(gè)職員擁有鑰匙。若沒有鑰匙就不能使用復(fù)印機(jī)。#t#
給共享變量上Java多線程鎖就使得Java線程能夠快速方便地通信和同步。某個(gè)線程若給一個(gè)對(duì)象上了鎖,就可以知道沒有其他線程能夠訪問該對(duì)象。即使在搶占式模型中,其他線程也不能夠訪問此對(duì)象,直到上鎖的線程被喚醒、完成工作并開鎖。那些試圖訪問一個(gè)上鎖對(duì)象的線程通常會(huì)進(jìn)入睡眠狀態(tài),直到上鎖的線程開鎖。一旦鎖被打開,這些睡眠進(jìn)程就會(huì)被喚醒并移到準(zhǔn)備就緒隊(duì)列中。
在Java編程中,所有的對(duì)象都有鎖。線程可以使用synchronized關(guān)鍵字來(lái)獲得鎖。在任一時(shí)刻對(duì)于給定的類的實(shí)例,方法或同步的代碼塊只能被一個(gè)線程執(zhí)行。這是因?yàn)榇a在執(zhí)行之前要求獲得對(duì)象的Java多線程鎖。繼續(xù)我們關(guān)于復(fù)印機(jī)的比喻,為了避免復(fù)印沖突,我們可以簡(jiǎn)單地對(duì)復(fù)印資源實(shí)行同步。如同下列的代碼例子,任一時(shí)刻只允許一位職員使用復(fù)印資源。通過(guò)使用方法(在 Copier 對(duì)象中)來(lái)修改復(fù)印機(jī)狀態(tài)。這個(gè)方法就是同步方法。只有一個(gè)線程能夠執(zhí)行一個(gè)Copier對(duì)象中同步代碼,因此那些需要使用Copier對(duì)象的職員就必須排隊(duì)等候。
- class CopyMachine {
- public synchronized void makeCopies(Document d, int nCopies) {
- //only one thread executes this at a time
- }
- public void loadPaper() {
- //multiple threads could access this at once!
- synchronized(this) {
- //only one thread accesses this at a time
- //feel free to use shared resources, overwrite members, etc.
Fine-grain Java多線程鎖
在對(duì)象級(jí)使用鎖通常是一種比較粗糙的方法。為什么要將整個(gè)對(duì)象都上鎖,而不允許其他線程短暫地使用對(duì)象中其他同步方法來(lái)訪問共享資源?如果一個(gè)對(duì)象擁有多個(gè)資源,就不需要只為了讓一個(gè)線程使用其中一部分資源,就將所有線程都鎖在外面。由于每個(gè)對(duì)象都有Java多線程鎖,可以如下所示使用虛擬對(duì)象來(lái)上鎖:
- class FineGrainLock {
- MyMemberClass x, y;
- Object xlock = new Object(), ylock = new Object();
- public void foo() {
- synchronized(xlock) {
- //access x here
- }
- //do something here - but don't use shared resources
- synchronized(ylock) {
- //access y here
- }
- }
- public void bar() {
- synchronized(this) {
- //access both x and y here
- }
- //do something here - but don't use shared resources
- }
- }
若為了在方法級(jí)上同步,不能將整個(gè)方法聲明為synchronized關(guān)鍵字。它們使用的是成員Java多線程鎖,而不是synchronized方法能夠獲得的對(duì)象級(jí)鎖。