好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java线程使用同步锁交替执行打印奇数偶数的方法

对同一个对象进行多线程操作时,如何保证线程执行结果的一致性?我们需要对线程操作对象加同步锁。(这是一道面试题)

需求描述

1-20个数字

a线程打印奇数:1,3,5,7,9,11,13,15,17,19

b线程打印偶数:2,4,6,8,10,12,14,16,18,20

c线程在ab两个线程执行完了之后打印结果:[success]。

线程代码实现

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: 学习需要毅力,那就秀毅力

  * @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(奇数线程)

* @author: pengjunlin

* @motto: 学习需要毅力,那就秀毅力

* @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(偶数线程)

  * @author: pengjunlin

  * @motto: 学习需要毅力,那就秀毅力

  * @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(等待结果线程)

  * @author: pengjunlin

  * @motto: 学习需要毅力,那就秀毅力

  * @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: 学习需要毅力,那就秀毅力

  * @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();

   }

}

测试结果

?

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 作为方法块使用时需要只能对对象加锁,不能是常用数据类型。

ab线程改进:使用线程等待和通知

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(奇数线程)

* @author: pengjunlin

* @motto: 学习需要毅力,那就秀毅力

* @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(偶数线程)

  * @author: pengjunlin

  * @motto: 学习需要毅力,那就秀毅力

  * @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();

             }

           }

         }

       }

     }

  }

注:线程等待和通知的操作是节省cpu运算的一种方式,避免cpu空转(线程方法一直不停地跑类似于死循环是很可怕的),如果是要让线程停下来需要调用线程的wait()。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/boonya/article/details/86485504

查看更多关于Java线程使用同步锁交替执行打印奇数偶数的方法的详细内容...

  阅读:11次