- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- java多線(xiàn)程累加計數的實(shí)現方法
給定count=0;讓5個(gè)線(xiàn)程并發(fā)累加到1000;
注意
這塊注意Thread和Runnable類(lèi)的區別,Thread類(lèi)是線(xiàn)程類(lèi),可以直接new Thread().start運行。而Runnable類(lèi)是任務(wù)類(lèi),需要一個(gè)線(xiàn)程來(lái)承載任務(wù),通過(guò)new Thread(new Runnable()).start()來(lái)運行任務(wù)。
方法一
將count公共變量放到測試類(lèi)Test的類(lèi)成員變量里,將MyRunnable類(lèi)作為T(mén)est類(lèi)的內部類(lèi),在Test類(lèi)的main方法里創(chuàng )建5個(gè)線(xiàn)程,實(shí)現累加。
代碼
public class Test { //公共變量 int count=0; public static void main(String[] args){ //new一個(gè)實(shí)現Runnable的類(lèi) Test test=new Test(); //創(chuàng )建5個(gè)任務(wù) MyRunnable myRunnable1=test.new MyRunnable(); MyRunnable myRunnable2=test.new MyRunnable(); MyRunnable myRunnable3=test.new MyRunnable(); MyRunnable myRunnable4=test.new MyRunnable(); MyRunnable myRunnable5=test.new MyRunnable(); //創(chuàng )建5個(gè)線(xiàn)程 new Thread(myRunnable1).start(); new Thread(myRunnable2).start(); new Thread(myRunnable3).start(); new Thread(myRunnable4).start(); new Thread(myRunnable5).start(); } //創(chuàng )建一個(gè)實(shí)現Runnable的類(lèi) class MyRunnable implements Runnable{ public void run() { while(true){ //鎖住的是整個(gè)MyRunnable類(lèi) synchronized(MyRunnable.class){ if(count>=1000){ break; } System.out.println(Thread.currentThread().getName()+":count:"+(++count)); //測試時(shí),線(xiàn)程更容易切換 Thread.yield(); } } } } }
方法二
以上代碼沒(méi)有問(wèn)題,成功實(shí)現5個(gè)線(xiàn)程累加count到1000,接下來(lái)我們將上邊代碼稍作修改。
代碼
public class Test { //公共變量 int count=0; public static void main(String[] args){ //new一個(gè)實(shí)現Runnable的類(lèi) Test test=new Test(); //創(chuàng )建1個(gè)任務(wù) MyRunnable myRunnable1=test.new MyRunnable(); // MyRunnable myRunnable2=test.new MyRunnable(); // MyRunnable myRunnable3=test.new MyRunnable(); // MyRunnable myRunnable4=test.new MyRunnable(); // MyRunnable myRunnable5=test.new MyRunnable(); //創(chuàng )建5個(gè)線(xiàn)程 for(int i=0;i<4;i++){ new Thread(myRunnable1).start(); } // new Thread(myRunnable2).start(); // new Thread(myRunnable3).start(); // new Thread(myRunnable4).start(); // new Thread(myRunnable5).start(); } //創(chuàng )建一個(gè)實(shí)現Runnable的類(lèi) class MyRunnable implements Runnable{ public void run() { while(true){ //鎖住的是同一對象 synchronized(this){ if(count>=1000){ break; } System.out.println(Thread.currentThread().getName()+":count:"+(++count)); //測試時(shí),線(xiàn)程更容易切換 Thread.yield(); } } } } }
以上代碼沒(méi)有問(wèn)題,成功實(shí)現5個(gè)線(xiàn)程累加count到1000。
雖然結果是一樣的,但是代碼實(shí)現是不一樣的,代碼一是創(chuàng )建了5個(gè)MyRunnable對象,代碼二只創(chuàng )建了1個(gè)MyRunnable對象??紤]并發(fā)時(shí)用到的鎖就是不一樣的,
代碼一和代碼二雖然synchronized中的鎖不同,但目的都是為了括號中的鎖是恒定不變的。
方法三
使用AtomicInteger類(lèi),來(lái)實(shí)現多線(xiàn)程累加,AtomicInteger類(lèi)是線(xiàn)程安全的,使用它的優(yōu)點(diǎn)就是我們不需要在代碼里寫(xiě)Synchronized關(guān)鍵字了,這些事都交給它去做了。
代碼
public class Test { static CountDownLatch cdl=new CountDownLatch(1000);; static AtomicInteger ai=new AtomicInteger(0); public static void main(String[] args) throws InterruptedException{ ExecutorService exec=Executors.newFixedThreadPool(100); for (int i = 0; i < 1000; i++) { exec.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+":"+ai.getAndIncrement()); cdl.countDown(); } }); } cdl.await(); System.out.println(ai.get()); exec.shutdown(); } }
代碼中用到了CountDownLatch類(lèi),用法就是給其設定一個(gè)初始值1000,然后在不同線(xiàn)程中執行countDown方法,每執行一次,初始值-1,await方法就是等初始值減到0時(shí),停止等待,否則一直等待。
我在代碼里新建了100個(gè)線(xiàn)程來(lái)并發(fā)累加,讓我們看下最后結果。
控制臺輸出如下:
可以看到雖然輸出不是按照順序輸出的,但是最后的結果是我們想要的結果,沒(méi)有出現重復值的情況。
這到題目只是舉了一個(gè)多線(xiàn)程的例子,以及鎖的簡(jiǎn)單知識。在實(shí)際應用中,從0累加到1000用多線(xiàn)程是沒(méi)有意義的。因為根本不會(huì )比單線(xiàn)程快。就像讓一個(gè)人數數,從0數到1000,或者讓5個(gè)人接替數到1000,應該一個(gè)人更快點(diǎn)吧,5個(gè)人還要考慮配合的問(wèn)題。但假如這5個(gè)人都是磕巴(口語(yǔ)不好),一個(gè)人每讀一個(gè)數都要停頓1秒,但是讓5個(gè)人協(xié)作,省去中間的等待時(shí)間,才是多線(xiàn)程應用的真正意義。
多線(xiàn)程的真正應用應該是,任務(wù)中有等待的時(shí)間,這個(gè)等待時(shí)間如果交給一個(gè)線(xiàn)程做就堵塞在這塊了。如果交由多個(gè)線(xiàn)程去做,會(huì )充分利用等待時(shí)間,去做其他事情。這才是多線(xiàn)程的意思。在我們日常工作中,像IO,網(wǎng)絡(luò ),圖片處理等,有些地方都是需要等待的,這幾塊用多線(xiàn)程,可能會(huì )提高效率。
當然,也有一種情況,比如多個(gè)用戶(hù)訪(fǎng)問(wèn)后臺接口,每個(gè)用戶(hù)訪(fǎng)問(wèn)其實(shí)都是一個(gè)單獨的線(xiàn)程,假如想計算累計有多少次訪(fǎng)問(wèn)的話(huà),就需要用到多線(xiàn)程累加。
同類(lèi)型文章
感興趣的也可以參考我的另外一篇文章,
到此這篇關(guān)于java多線(xiàn)程累加計數的實(shí)現方法的文章就介紹到這了,更多相關(guān)java多線(xiàn)程累加計數內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站