您好,登录后才能下订单哦!
密码登录
            
            
            
            
        登录注册
            
            
            
        点击 登录注册 即表示同意《亿速云用户服务条款》
        对同一个对象进行多线程操作时,如何保证线程执行结果的一致性?我们需要对线程操作对象加同步锁。(这是一道面试题)
需求描述
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()。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持亿速云。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。