對同一個對象進(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
1
2
3
4
5
6
7
8
9
10
11
12
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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é)果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
"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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
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運算的一種方式,避免cpu空轉(zhuǎn)(線程方法一直不停地跑類似于死循環(huán)是很可怕的),如果是要讓線程停下來需要調(diào)用線程的wait()。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/boonya/article/details/86485504