㈠ java中線程同步的幾種方法
線程同步主要有以下種方法(示例中是實現計數的功能):
1、同步方法,即使用synchronized關鍵字修飾方法,例如:
publicsynchronizedvoidadd(intc){...}
2、同步代碼塊,即有synchronized關鍵字修飾的語句塊,例如:
publicvoidaddAndGet(intc){
synchronized(this){
count+=c;
}
}
3、使用特殊域變數(volatile)實現線程同步,該方法不能保證絕對的同步。
例如:privatevolatileintcount=0;
4、使用鎖實現線程同步,例如:
privateLocklock=newReentrantLock();
publicvoidadd(intc){
lock.lock();//上鎖
try{
count+=c;
}finally{
lock.unlock();//解鎖
}
}
5、使用原子變數實現線程同步,在java的util.concurrent.atomic包中提供了創建了原子類型變數的工具類,例如:
privateAtomicIntegercount=newAtomicInteger(1);
publicvoidadd(intc){
count.addAndGet(c);
}
6、使用局部變數實現線程同步,如果使用ThreadLocal管理變數,則每一個使用該變數的線程都獲得該變數的副本, 副本之間相互獨立,這樣每一個線程都可以隨意修改自己的變數副本,而不會對其他線程產生影響。
ThreadLocal 類的常用方法
new ThreadLocal<T>() : 創建一個線程本地變數
get() : 返回此線程局部變數的當前線程副本中的值
initialValue() : 返回此線程局部變數的當前線程的"初始值"
set(T value) : 將此線程局部變數的當前線程副本中的值設置為value
示例代碼:
privatestaticThreadLocal<Integer>count=newThreadLocal<Integer>(){
@Override
protectedIntegerinitialValue(){
return1;
}
};
publicvoidadd(intc){
count.set(count.get()+c);
}
7、使用阻塞隊列實現,例如LinkedBlockingQueue,具體使用可網路LinkedBlockingQueue的用法或查看java文檔。
㈡ JAVA多線程同步問題
噢,是這樣的,不是什麼東西都能當做鎖,你不能這樣理解。
synchronized(obj),obj這里是你所在類的MIDlet的一個實例對象。
目的是解決因線程不同步而對數據造成破壞的問題。
假如:在一個類中有一個成員變數a,還有兩個線程,如果線程不同步的話,這兩個線程有可能同時訪問同一個變數a,這樣的話,就會出現問題,最後執的結果a到底是幾呢,所以就要使用線程同步這個辦法了。
使用線程同步後,線程1在訪問a的時候,我加了一把鎖,在這個時候別的線程是不允許訪問a的,等線程1對a有訪問結束後,就會去掉這把鎖,其他的線程再訪問a的時候,又會加鎖,這樣在同一時候,只能有一方訪問a,這樣就不會出現問題,我說這么多,你明白了嗎?希望你能明白,不然我說的算白說了,呵呵!!!!
㈢ Java多線程伺服器的同步問題
多線程之所以會出現同步問題,是因為多個線程可以共享資源,對同一資源進行操作,導致不一致的問題,你這個並沒有對什麼資源進行操作,不會有問題
㈣ Java如何處理多線程的數據同步問題
通過synchronize加鎖進行實現進行之間的互斥、通過wait、notify方法實現線程之間的同步。
㈤ Java多線程同步的幾種方式
java中多線程的實現方法有兩種:1.直接繼承thread類;2.實現runnable介面;同步的實現方法有五種:1.同步方法;2.同步代碼塊;3.使用特殊域變數(volatile)實現線程同步;4.使用重入鎖實現線程同步;5.使用局部變數實現線程同步 。
其中多線程實現過程中需注意重寫或者覆蓋run()方法,而對於同步的實現方法中使用較常使用的是利用synchronized編寫同步方法和代碼塊。
謝謝採納!!
㈥ java多線程同步問題!
對於這個列子來說確實可以不用加資源同步鎖,
其實只有對別的線程可能改變其它線程把持的對象的值的情況才要考慮是否需要同步鎖,對於不會改變的情況一般不用考慮,這里的taskList 對象很可能被多個線程同時修改,所以考慮了同步鎖,其實List對象的add永遠也不會出現添加出錯的情況,所以其實這里沒什麼必要加上同步鎖。
而對象一旦加上同步鎖,那麼當某個線程獲得該對象資源,那麼該資源被鎖定,只能由該線程可以操作,而Object.notify()方法是釋放掉該資源,處於等待狀態的其它線程可以獲得該資源,如果不顯示聲明notify,當synchronized塊執行完後會自動釋放。
㈦ java多線程解決同步問題的幾種方式,原理和代碼
在Java中一共有四種方法支持同步,其中前三個是同步方法,一個是管道方法。管道方法不建議使用。
wait()/notify()方法
await()/signal()方法
BlockingQueue阻塞隊列方法
PipedInputStream/PipedOutputStream
阻塞隊列的一個簡單實現:
在enqueue和dequeue方法內部,只有隊列的大小等於上限(limit)或者下限(0)時,才調用notifyAll方法。如果隊列的大小既不等於上限,也不等於下限,任何線程調用enqueue或者dequeue方法時,都不會阻塞,都能夠正常的往隊列中添加或者移除元素。
wait()/notify()方法
生產者的主要作用是生成一定量的數據放到緩沖區中,然後重復此過程。與此同時,消費者也在緩沖區消耗這些數據。該問題的關鍵就是要保證生產者不會在緩沖區滿時加入數據,消費者也不會在緩沖區中空時消耗數據。
要解決該問題,就必須讓生產者在緩沖區滿時休眠(要麼乾脆就放棄數據),等到下次消費者消耗緩沖區中的數據的時候,生產者才能被喚醒,開始往緩沖區添加數據。同樣,也可以讓消費者在緩沖區空時進入休眠,等到生產者往緩沖區添加數據之後,再喚醒消費者。
㈧ java多線程同步的問題
用連接池很好搞定,就是系統開銷會大些,連接池的回收會有一些麻煩。
主進程
packageorg.test;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.ExecutionException;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
importjava.util.concurrent.Future;
importjava.util.concurrent.TimeUnit;
importjava.util.concurrent.TimeoutException;
publicclassTestTheadPool{
publicstaticvoidmain(String[]args){
Future<String>future=null;//每次請求,返回的執行結果
ExecutorServicepool=Executors.newFixedThreadPool(3);//執行pool初始化線程3個分別用於做任務A,任務B,任務C
List<Future<String>>futureList=newArrayList<Future<String>>();//執行結果集
//非同步請求調用A
futureList.add(pool.submit(newAsynProcessThread("A")));
//非同步請求調用B
futureList.add(pool.submit(newAsynProcessThread("B")));
//非同步請求調用C
futureList.add(pool.submit(newAsynProcessThread("C")));
try{
for(inti=0;i<futureList.size();i++){
StringtempResult="";
tempResult=futureList.get(i).get(30000,TimeUnit.MILLISECONDS);//設定超時時間
System.out.println("future["+i+"]result="+tempResult);
}
}catch(InterruptedExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(ExecutionExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}catch(TimeoutExceptione){
//TODOAuto-generatedcatchblock
e.printStackTrace();
}finally{
pool.shutdown();//這個連接池回收比較簡單,沒有考慮回收失敗的情況。
}
//startprocessD
System.out.println("itisprocessDstart");
System.out.println("itisprocessDend");
}
}
非同步線程類
packageorg.test;
importjava.util.Date;
importjava.util.concurrent.Callable;
<String>{
privateStringprocessType;
//構造器
publicAsynProcessThread(StringprocessType){
this.processType=processType;
}
@Override
publicStringcall()throwsException{
DatestartDate=newDate();
System.out.println("process"+processType+"start,time=["+startDate.getTime()+"]");
if("A".equals(processType)){
Thread.sleep(10000);//sleep10秒
}elseif("B".equals(processType)){
Thread.sleep(20000);//sleep20秒
}elseif("C".equals(processType)){
Thread.sleep(15000);//sleep15秒
}
DateendDate=newDate();
System.out.println("process"+processType+"end,time=["+endDate.getTime()+"]total=["+(endDate.getTime()-startDate.getTime())+"]");
return"SUCCESS";
}
}
㈨ JAVA多線程同步的問題
很簡單,當不使用的時候,所有的線程都在運行這一個run,因為你沒鎖,也就是說沒鎖的聽況下,看似只有一個runnable對象,一個run代碼塊,但是四個線程都在用,這相當於一個房間裡面有100本書,是個人都可以同時進入拿,自然四個線程都參與,當你鎖起來的時候就相當於一個人進入了就鎖了門,其他人都進不去了,只有當那個人出來了,其他人才可以進去,但是,裡面是死循環,知道書被那個人都裝進麻袋了猜背出來,其他人進去了已經沒有了,所以循環直接退出。這樣就看似只有一個線程在執行了。