国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作

瀏覽:48日期:2022-08-26 09:16:08

首先打印1-100數(shù)字如果用一個(gè)單線程實(shí)現(xiàn)那么只要一個(gè)for循環(huán)即可,那么如果要用兩個(gè)線程打印出來(lái)呢?(一個(gè)線程打印奇數(shù),一個(gè)線程打印偶數(shù))于是大家會(huì)想到可以通過(guò)加鎖實(shí)現(xiàn),但是這樣的效率是不是不高?這里我用一個(gè)變量來(lái)控制兩個(gè)線程的輸出

public class ThreadTest { volatile int flag=0; public void runThread() throws InterruptedException{ Thread t1=new Thread(new Thread1()); Thread t2=new Thread(new Thread2()); t1.start(); t2.start(); } public class Thread1 implements Runnable{ public void run() { int i=0; while(i<=99){ if(flag==0) { System.out.println('t1='+i+'flag='+flag); i+=2; flag=1; } } } } public class Thread2 implements Runnable{ public void run() { int i=1; while(i<=99){ if(flag==1) { System.out.println('t2='+i+'flag='+flag); i+=2; flag=0; } } } }}

那么如果要實(shí)現(xiàn)三個(gè)線程輪流打印1-100的數(shù)字呢?是不是也可以用上面的方法實(shí)現(xiàn)呢?代碼如下

public class ThreadTest { private int i=0; private Thread thread1,thread2,thread3; private int flag=0; public void runThread() throws InterruptedException{ thread1=new Thread(new Thread1()); thread2=new Thread(new Thread2()); thread3=new Thread(new Thread3()); thread1.start(); thread2.start(); thread3.start(); } public class Thread1 implements Runnable{ public void run() { while(i<=100){ if(flag==0) { System.out.println('t1='+i); i++; flag=1; } } } } public class Thread2 implements Runnable{ public void run() { while(i<=100){ if(flag==1) { System.out.println('t2='+i); i++; flag=2; } } } } public class Thread3 implements Runnable{ public void run() { while(i<=100){ if(flag==2) { System.out.println('t3='+i); i++; flag=0; } } } }}

運(yùn)行結(jié)果

Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作

發(fā)現(xiàn)三個(gè)線程只打印了一次就停止不輸出了,是什么原因呢?

可以用jdk自帶的jstack來(lái)看看線程的狀態(tài),在windows系統(tǒng)中可以打開(kāi)cmd然后進(jìn)入jdk所在目錄,然后執(zhí)行Jsp,能查看到各線程id,然后執(zhí)行jstack -F pid就可以看的狀態(tài)了

Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作

可以看到幾個(gè)Thread state是BLOCKED,就是阻塞了,什么原因呢?

尷尬發(fā)現(xiàn)flag變量和i變量前面忘記加volatile,導(dǎo)致flag和i被線程讀取修改時(shí),其他線程不可見(jiàn),所以才導(dǎo)致上面的問(wèn)題出現(xiàn)。

在JVM中每個(gè)線程讀取變量到cache中時(shí)相互都是不可見(jiàn)的,也就是java五大內(nèi)存區(qū)中的程序計(jì)數(shù)器區(qū)域?qū)τ诿總€(gè)線程都是獨(dú)立的不共享的,只有堆內(nèi)存區(qū)和方法區(qū)是對(duì)所有線程都是共享的。

當(dāng)線程1讀取了flag和i的值,并對(duì)其進(jìn)行修改的時(shí)候,線程2并發(fā)運(yùn)行,并不知道flag和i值已經(jīng)改變,導(dǎo)致多線程數(shù)據(jù)不一致的情況,所以加了volatile后,當(dāng)線程讀取變量進(jìn)行修改后會(huì)“通知”其它線程這個(gè)值已經(jīng)進(jìn)行了修改。

import java.util.concurrent.atomic.AtomicInteger; public class ThreadTest { private volatile int i=0; private Thread thread1,thread2,thread3; private volatile int flag=0; public void runThread() throws InterruptedException{ thread1=new Thread(new Thread1()); thread2=new Thread(new Thread2()); thread3=new Thread(new Thread3()); thread1.start(); thread2.start(); thread3.start(); } public class Thread1 implements Runnable{ public void run() { while(i<100){ if(flag==0) { System.out.println('t1='+i); i++; flag=1; } } } } public class Thread2 implements Runnable{ public void run() { while(i<100){ if(flag==1){ System.out.println('t2='+i); i++; flag=2; } } } } public class Thread3 implements Runnable{ public void run() { while(i<100){ if(flag==2){ System.out.println('t3='+i); i++; flag=0; } } } }}

運(yùn)行結(jié)果

Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作

-----未完-----

補(bǔ)充知識(shí):Java n個(gè)線程輪流打印數(shù)字的問(wèn)題

一、兩個(gè)線程輪流打印數(shù)字。

加鎖實(shí)現(xiàn):

package lianxi; /* * 用鎖實(shí)現(xiàn)兩個(gè)線程輪流打印1——100 */public class Print1TO100TwoThread { private Object lock = new Object(); private int i = 0; Thread threadA = new Thread(new Runnable() { @Override public void run() { while (i <= 100) { synchronized (lock) { try { if (i > 100) break; System.out.println('threadA :' + (i++)); lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { while (i <= 100) { synchronized (lock) { try { if (i > 100) break; System.out.println('threadB :' + (i++)); lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } }); public void startTwoThread() throws InterruptedException { threadA.start(); Thread.sleep(20); threadB.start(); } public static void main(String[] args) throws InterruptedException { new Print1TO100TwoThread().startTwoThread(); } }

用鎖效率太低,用一個(gè)變量來(lái)控制打印的順序。

package lianxi;/* * 用兩個(gè)線程輪流打印1——10;用所實(shí)現(xiàn)效率太低,用變量來(lái)控制 */public class PrinntNumTwoThread { private volatile int num = 0; private volatile boolean flag = false; Thread threadA = new Thread(new Runnable() { @Override public void run() { while (true) { if (num > 10) return; if (!flag) { System.out.println('threadA-->' + ':' + (num++)); flag = !flag; } } } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { while (true) { if (num > 10) return; if (flag) { System.out.println('threadB-->' + ':' + (num++)); flag = !flag; } } } }); public void startTwoThread() { threadA.start(); threadB.start(); } public static void main(String[] args) { new PrinntNumTwoThread().startTwoThread(); }}

二、那么如果要實(shí)現(xiàn)三個(gè)線程輪流打印1-100的數(shù)字呢?

package lianxi; public class PrintNumThreeThread { private volatile int i = 0; private volatile int flag = 0; Thread threadA = new Thread(new Runnable() { @Override public void run() { while (true) { if (i > 100) return; if (flag == 0) { System.out.println('threadA->' + ':' + (i++)); flag = 1; } } } }); Thread threadB = new Thread(new Runnable() { @Override public void run() { while (true) { if (i > 100) return; if (flag == 1) { System.out.println('threadB->' + ':' + (i++)); flag = 2; } } } }); Thread threadC = new Thread(new Runnable() { @Override public void run() { while (true) { if (i > 100) return; if (flag == 2) { System.out.println('threadC->' + ':' + (i++)); flag = 0; } } } }); public void startThreeThread() { threadA.start(); threadB.start(); threadC.start(); } public static void main(String[] args) { new PrintNumThreeThread().startThreeThread(); }}

以上這篇Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 精品亚洲一区二区 | 久久成人小视频 | 国产精品深爱在线 | 国产成人一区二区三中文 | 天天看夜夜 | 中文久久 | 国产男女视频在线观看 | 国产精品久久久久久久久久日本 | 亚洲国产精品成人午夜在线观看 | 免费国产成人高清视频网站 | 久久不见久久见免费影院 | 欧美三级成人观看 | 久久久9视频在线观看 | 亚洲精品免费视频 | 国产精品观看 | 亚洲精品中文字幕在线 | 亚洲日本一区二区三区高清在线 | 国产精品路边足疗店按摩 | 国产孕妇孕交视频 | 亚洲欧美一区二区三区 | 精品爱爱 | 2021国产成人精品久久 | 亚洲一区成人 | 一本色道久久88亚洲综合 | 高清一级毛片免免费看 | 国产精品揄拍一区二区 | 99久久精品国产一区二区 | 精品久久久久久国产免费了 | 香蕉视频在线观看黄 | 香蕉毛片a | 一个人看的免费观看日本视频www | 午夜爽爽爽 | 免费观看a黄一级视频 | 日本三级香港三级人妇99 | 亚洲精品欧美精品国产精品 | 一级做a| 在线观看亚洲精品专区 | 欧美成人看片一区二区三区 | 欧美性三级 | a级毛片免费高清视频 | 亚洲激情欧美 |