Java線程使用同步鎖交替執(zhí)行打印奇數(shù)偶數(shù)的方法
對同一個對象進(jìn)行多線程操作時,如何保證線程執(zhí)行結(jié)果的一致性?我們需要對線程操作對象加同步鎖。(這是一道面試題)
需求描述
1-20個數(shù)字
A線程打印奇數(shù):1,3,5,7,9,11,13,15,17,19
B線程打印偶數(shù):2,4,6,8,10,12,14,16,18,20
C線程在AB兩個線程執(zhí)行完了之后打印結(jié)果:“success”。
線程代碼實現(xiàn)
Num.java
package com.boonya.thread.test;
/**
* @ClassName: Num
* @Description: TODO(加鎖計算對象)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:47
*/
public class Num {
int value=1;
}
AThread.java
package com.boonya.thread.test;
/**
* @ClassName: AThread
* @Description: TODO(奇數(shù)線程)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:26
*/
public class AThread implements Runnable{
Num num;
public AThread(Num num){
this.num=num;
}
public void run() {
while (num.value<20){
synchronized (num){
if(num.value%2!=0){
System.out.println("AThread:"+ num.value);
num.value++;
}
}
}
}
}
BThread.java
package com.boonya.thread.test;
/**
* @ClassName: BThread
* @Description: TODO(偶數(shù)線程)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:26
*/
public class BThread implements Runnable {
Num num;
public BThread(Num num){
this.num=num;
}
public void run() {
while (num.value<=20){
synchronized (num){
if(num.value%2==0){
System.out.println("BThread:"+ num.value);
num.value++;
}
}
}
}
}
CThread.java
package com.boonya.thread.test;
/**
* @ClassName: CThread
* @Description: TODO(等待結(jié)果線程)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:26
*/
public class CThread implements Runnable {
Num num;
public CThread(Num num){
this.num=num;
}
public void run() {
while (num.value<20){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("CThread:success!");
}
}
MainTest.java
package com.boonya.thread.test;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: MainTest
* @Description: TODO(線程測試)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 21:54
*/
public class MainTest {
public static void main(String[] args) {
Num num=new Num();
Thread a=new Thread(new AThread(num));
Thread b=new Thread(new BThread(num));
Thread c=new Thread(new CThread(num));
a.start();
b.start();
c.start();
}
}
測試結(jié)果
"C:\Program Files\Java\jdk1.8.0_121\bin\java" "-javaagent:C:\Users\boonya\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.2.5\lib\idea_rt.jar=51911:C:\Users\boonya\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.2.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_121\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_121\jre\lib\rt.jar;C:\Users\boonya\Desktop\JavaAlgorithm\target\test-classes;C:\Users\boonya\Desktop\JavaAlgorithm\target\classes" com.boonya.thread.test.MainTest AThread:1 BThread:2 AThread:3 BThread:4 AThread:5 BThread:6 AThread:7 BThread:8 AThread:9 BThread:10 AThread:11 BThread:12 AThread:13 BThread:14 AThread:15 BThread:16 AThread:17 BThread:18 AThread:19 BThread:20 CThread:success! Process finished with exit code 0
注意:synchronized 作為方法塊使用時需要只能對對象加鎖,不能是常用數(shù)據(jù)類型。
AB線程改進(jìn):使用線程等待和通知
AThread.java
package com.boonya.thread.test;
/**
* @ClassName: AThread
* @Description: TODO(奇數(shù)線程)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:26
*/
public class AThread implements Runnable{
Num num;
public AThread(Num num){
this.num=num;
}
public void run() {
while (num.value<20){
synchronized (num){
if(num.value%2!=0){
System.out.println("AThread:"+ num.value);
num.value++;
//num.notify();
num.notifyAll();
}else{
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
BThread.java
package com.boonya.thread.test;
/**
* @ClassName: BThread
* @Description: TODO(偶數(shù)線程)
* @author: pengjunlin
* @motto: 學(xué)習(xí)需要毅力,那就秀毅力
* @date 2019-01-14 22:26
*/
public class BThread implements Runnable {
Num num;
public BThread(Num num){
this.num=num;
}
public void run() {
while (num.value<=20){
synchronized (num){
if(num.value%2==0){
System.out.println("BThread:"+ num.value);
num.value++;
//num.notify();
num.notifyAll();
}else{
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
注:線程等待和通知的操作是節(jié)省CPU運(yùn)算的一種方式,避免CPU空轉(zhuǎn)(線程方法一直不停地跑類似于死循環(huán)是很可怕的),如果是要讓線程停下來需要調(diào)用線程的wait()。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決mybatis-generator生成Mapper文件沒有Selective結(jié)尾的問題
這篇文章主要介紹了解決mybatis-generator生成Mapper文件沒有Selective結(jié)尾的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
JAVA SpringBoot jar程序 Systemctl生產(chǎn)環(huán)境部署方案
這篇文章主要介紹了JAVA SpringBoot jar程序 Systemctl生產(chǎn)環(huán)境部署方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
Springboot獲取bean實例之SpringContextUtil詳解
這篇文章主要介紹了Springboot獲取bean實例之SpringContextUtil使用,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-03-03
解決maven打包排除類不生效maven-compiler-plugin問題
總結(jié):在Spring Boot項目B中作為項目A的依賴時,排除啟動類不生效的原因是被其他類引用或父POM引入,解決方法是跳過test編譯或注釋掉@SpringBootTest(classes={BApplication.class})2024-11-11

