线程同步的作用包含2个方面:

1.原子性:这里的原子性跟数据库事物的原子性相似,不论多个可变状态变量还是单个可变状态变量,要保证并发操作的正确性,必须保证每个线程拿到的数据都是正确的,不存在过期数据或者部分过期数据。最常见的违反原子性错误的情形是:"select-updatye"、"check-use"、"read-change-write",由于最终使用数据要依赖数据以前的状态,不是一个原子的操作,就容易因为线程执行时序的不同而导致结果不同。

2.可见性:可见性是指一个线程的数据状态对另一个线程是不是可见的,如果不可见,则A线程对共享数据的操作结果,B线程是拿不到的。

public class ShareStateTest {

    public static  boolean ready = false;
    public static  int num = 0;

    public static void main(String[] args){
         new Thread(){
            @Override
            public void run() {
                while(true) {
                    while(!ready){
                        System.out.println(Thread.currentThread().getId() + "It's not ready! num = " + num);
                    }
                    System.out.println(Thread.currentThread().getId() + "It's ready! num=" + num);
                }
            }
        }.start();
         new Thread(){
             @Override
             public void run() {
                 while(true) {
                     try {
                         Thread.sleep(1000);
                     } catch (InterruptedException e) {
                         e.printStackTrace();
                     }
                     while(!ready){
                         ready = true;
                         num = 2;
                         System.out.println("" + Thread.currentThread().getId() + " ready is true and num is " + num);
                     }
                 }
             }
         }.start();
    }
}

这里涉及到多线程调试,我用的是IDEA,设置好断点,鼠标右键,出现DEBUG选择框,按下图配置就可以进行多线程调试,IEAD还可以设置进入断点的条件。

线程同步之可见性试验

然后,开启DUBUG模式,可以看到线程不是并行执行的,而是受到线程调度器的调度,起初一直运行第一个线程,然后,过了几个时间片,开始运行第二个线程,这时ready已经被置为true了,但是第一个线程依然看不到ready的值变为true,又过了几轮的交替执行,才看到第一个线程打印了第二个while循环后边的输出,我想这是因为第二个线程将ready的值写回主内存需要时间吧!

相关文章:

  • 2021-11-16
  • 2021-09-02
  • 2022-12-23
  • 2021-04-14
  • 2021-11-03
  • 2022-12-23
  • 2021-10-01
猜你喜欢
  • 2021-12-21
  • 2021-08-12
  • 2021-09-05
  • 2021-07-31
  • 2021-11-25
相关资源
相似解决方案