臨界區(qū)(Critical Section):適合一個(gè)進(jìn)程內(nèi)的多線程訪問公共區(qū)域或代碼段時(shí)使用
我們提供的服務(wù)有:成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、微信公眾號(hào)開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、競(jìng)秀ssl等。為上千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的競(jìng)秀網(wǎng)站制作公司
Java如何實(shí)現(xiàn)線程之間的互斥
互斥量 (Mutex):適合不同進(jìn)程內(nèi)多線程訪問公共區(qū)域或代碼段時(shí)使用,與臨界區(qū)相似。
事件(Event):通過線程間觸發(fā)事件實(shí)現(xiàn)同步互斥
信號(hào)量(Semaphore):與臨界區(qū)和互斥量不同,可以實(shí)現(xiàn)多個(gè)線程同時(shí)訪問公共區(qū)域數(shù)據(jù),原理與操作系統(tǒng)中PV操作類似,先設(shè)置一個(gè)訪問公共區(qū)域的線程最大連接數(shù),每有一個(gè)線程訪問共享區(qū)資源數(shù)就減一,直到資源數(shù)小于等于零。
import?java.util.concurrent.locks.ReentrantLock;
public?class?Test{
private?static?final?ReentrantLock?lock?=?new?ReentrantLock();
public?void?t1()?{
if(lock.tryLock())?{
System.out.println("t1");
}
}
public?void?t2()?{
if(lock.tryLock())?{
System.out.println("t2");
}
}
}
大致思路就是用同一個(gè)lock 來鎖住兩個(gè)方法,當(dāng)t1正在執(zhí)行時(shí),t2就直接跳過不會(huì)執(zhí)行了
你的對(duì)象都沒有調(diào)用方法b,對(duì)它都沒有約束,怎么可能限制其它對(duì)象不能訪問方法b
QUARTZ 集群 ,任務(wù)信息保存在數(shù)據(jù)庫(kù)中,通過數(shù)據(jù)庫(kù)做到集群控制。
數(shù)據(jù)庫(kù)讀寫的程度,這是事務(wù)控制數(shù)據(jù)庫(kù)隔離里面的內(nèi)容。
建議你使用spring聲明式事務(wù),并使用符合你的要求的事務(wù)隔離級(jí)別即可。
spring目前的提供支持的數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別有:
數(shù)據(jù)庫(kù)提供了四種事務(wù)隔離級(jí)別, 不同的隔離級(jí)別采用不同的鎖類開來實(shí)現(xiàn).
在四種隔離級(jí)別中, Serializable的級(jí)別最高, Read Uncommited級(jí)別最低.
大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別為: Read Commited,如Sql Server , Oracle.
少數(shù)數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別為Repeatable Read, 如MySQL InnoDB存儲(chǔ)引擎
即使是最低的級(jí)別,也不會(huì)出現(xiàn) 第一類 丟失 更新問題 .
Read Uncommited :讀未提交數(shù)據(jù)( 會(huì)出現(xiàn)臟讀,不可重復(fù)讀,幻讀 ,避免了 第一類丟失 更新 )
Read Commited :讀已提交的數(shù)據(jù)(會(huì)出現(xiàn)不可重復(fù)讀,幻讀)
Repeatable Read :可重復(fù)讀(會(huì)出現(xiàn)幻讀)
Serializable :串行化
作為一個(gè)完全面向?qū)ο蟮恼Z(yǔ)言,Java提供了類 Java.lang.Thread 來方便多線程編程,這個(gè)類提供了大量的方法來方便我們控制自己的各個(gè)線程,我們以后的討論都將圍繞這個(gè)類進(jìn)行。
Thread 類最重要的方法是 run() ,它為Thread 類的方法 start() 所調(diào)用,提供我們的線程所要執(zhí)行的代碼。為了指定我們自己的代碼,只需要覆蓋它!
方法一:繼承 Thread 類,覆蓋方法 run()
我們?cè)趧?chuàng)建的 Thread 類的子類中重寫 run() ,加入線程所要執(zhí)行的代碼即可。
下面是一個(gè)例子:
public class MyThread extends Thread {
int count= 1, number;
public MyThread(int num) {
number = num;
System.out.println("創(chuàng)建線程 " + number);
}
public void run() {
while(true) {
System.out.println("線程 " + number + ":計(jì)數(shù) " + count);
if(++count== 6) return;
}
}
public static void main(String args[]) {
for(int i = 0; i 5; i++) new MyThread(i+1).start();
}
}
這種方法簡(jiǎn)單明了,符合大家的習(xí)慣,但是,它也有一個(gè)很大的缺點(diǎn),那就是如果我們的類已經(jīng)從一個(gè)類繼承(如小程序必須繼承自 Applet 類),則無法再繼承 Thread 類,這時(shí)如果我們又不想建立一個(gè)新的類.
一種新的方法:不創(chuàng)建 Thread 類的子類,而是直接使用它,那么我們只能將我們的方法作為參數(shù)傳遞給 Thread 類的實(shí)例,有點(diǎn)類似回調(diào)函數(shù)。但是 Java 沒有指針,我們只能傳遞一個(gè)包含這個(gè)方法的類的實(shí)例。那么如何限制這個(gè)類必須包含這一方法呢?當(dāng)然是使用接口?。m然抽象類也可滿足,但是需要繼承,而我們之所以要采用這種新方法,不就是為了避免繼承帶來的限制嗎?)
Java 提供了接口 Java.lang.Runnable 來支持這種方法。
方法二:實(shí)現(xiàn) Runnable 接口
Runnable 接口只有一個(gè)方法 run(),我們聲明自己的類實(shí)現(xiàn) Runnable 接口并提供這一方法,將我們的線程代碼寫入其中,就完成了這一部分的任務(wù)。
但是 Runnable 接口并沒有任何對(duì)線程的支持,我們還必須創(chuàng)建 Thread 類的實(shí)例,這一點(diǎn)通過 Thread 類的構(gòu)造函數(shù)
public Thread(Runnable target);
來實(shí)現(xiàn)。
下面是一個(gè)例子:
public class MyThread implements Runnable {
int count= 1, number;
public MyThread(int num) {
number = num;
System.out.println("創(chuàng)建線程 " + number);
}
public void run() {
while(true) {
System.out.println("線程 " + number + ":計(jì)數(shù) " + count);
if(++count== 6) return;
}
}
public static void main(String args[])
{
for(int i = 0; i 5; i++) new Thread(new MyThread(i+1)).start();
}
}