评论

收藏

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

编程语言 编程语言 发布于:2021-10-05 16:44 | 阅读数:544 | 评论:0

这篇文章主要介绍了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
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
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
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
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
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();
  }
}
测试结果
"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
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
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()。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持CodeAE代码之家
原文链接:https://blog.csdn.net/boonya/article/details/86485504

关注下面的标签,发现更多相似文章