初探并发编程(一)AtomicInteger、Volatile关键字、可重入锁

1:为什么要引入AtomicInteger关键字

   在java中,多个线程访问一个共享变量时会发生线程安全问题。

  例子:

   Count类:

  主函数开三个线程:

   我们希望count的值为599,但是由于是多线程,所以结果如下:

 

  那么我们应该怎么处理呢?

         java为我们引入了一个包(atomic)来处理该情况。

代码如下:

  count类:

 结果如下:

  AtomicInteger关键字能保证变量值得准确性,但不能保证它们能按顺序输出。但一般我们都只是获取它的值,而不是打印它的值。

 如果你既想保证数字的准确性又想保证能按顺序输出,你只能用Synchronized关键字了

 代码如下:

 总结: synchronized关键字是一种内部锁,可以理解成一个小黑屋,每个线程走到被synchronized代码块包含的代码就像进入这个小黑屋,只能一个一个的操作。

2:volatile关键字

  被volatile修饰的变量,在多个线程下是可见的,其作用是让该变量在多哥线程下是透明的(让程序从内存中加载,不允许在缓存中加载)。可以保证变量的修改让所有线程可见;

代码:

   

 按我们所想,就俩线程不过怎么着,程序总会停止吧。但是,程序死在这里了。如图

   

为什么会这样?

   因为线程是CPU启动的,而CPU一开始从主存中取数据并没有立即将数据送到CPU,而是先送到了缓存中, 另外一个线程修改bChanged的值,是就该主存中的值,而那个输出结果的线程并没有从主存中取bChanged的值,而是去缓存中取了bChanged的值,而缓存中bChanged的值是false,这就是为什么会死循环的原因。如下图

 这个时候,java提供的volatile关键字就派上了用处。它保证了变量在线程之间的可见性。让程序不要去缓存中取值,而是去主存中取值。

 你会发现加上volatile关键字后,程序会秒停。 

3:可重入锁

一个线程获取它本身的锁是可以成功的,多个线程同时抢占同一个锁会失败。因为他们之间是互斥的。但是一个线程再次获取一个自己已经拿过的锁是可以成功的,这叫可重入锁机制 。

猜你喜欢

转载自blog.csdn.net/qq_36957587/article/details/84341252