JavaEE 线程安全

打印 上一主题 下一主题

主题 818|帖子 818|积分 2454

JavaEE 线程安全

近来重新开始复习多线程的知识,故此将线程安全这块重点单拎出来做文章记录,方便后续回想

  
1. 概念

什么是线程安全题目?很直观的说,就是一段代码,在单线程的环境下没有题目,但是在多线程的环境下却出现了题目,我们则可称这段代码存在线程安全题目
我们用代码举例:
   我如今有两个线程,我希望通过这两个线程来对一个变量count举行加法运算,每个线程各加50_0000,末了在主线程输出count
  代码如下:
  1. public class Test1 {
  2.     private static int count = 0;
  3.     public static void main(String[] args) throws InterruptedException {
  4.         Thread t1 = new Thread(() -> {
  5.             for (int i = 1;i <= 500000;i++) {
  6.                 count++;
  7.             }
  8.         });
  9.         Thread t2 = new Thread(() -> {
  10.             for (int i = 1;i <= 500000;i++) {
  11.                 count++;
  12.             }
  13.         });
  14.         t1.start();
  15.         t2.start();
  16.         t1.join();
  17.         t2.join();
  18.         System.out.println("count = " + count);
  19.     }
  20. }
复制代码
正常在单线程环境下,举行上述的代码操纵,末了得到的count会等于100_0000,但是在多线程的环境下,上述操纵得到的结果却不是我们所意推测的结果:

为什么相差这么多?且每次运行的结果都不一样!
根本原因便是线程之间的调度是无序的随机调度的,也称抢占式执行
正因如此,在上述代码中,两个线程对count这个对象的修改操纵会产生很多种情况:
   注:count++这个操纵本质上是由三条CPU指令构成的:
  

  • load:把内存中的数据加载到寄存器中;
  • add:将寄存器中的数据举行加1运算;
  • save:将寄存器中的数据写回到内存中;
  合理的情况:

不合理的情况:

上述的不合理情况还有多种,这里举最典型的情况,如上图,可以看到在多线程的环境下,线程的随机调度导致无法保证操纵的原子性,导致t1线程值还没修改完,t2线程就对count举行了修改,末了仍旧被t1线程修改后的旧值所覆盖,这也是我们上述代码得到结果不准确且不唯一的原因!
对此也得出一个结论:导致线程安全题目标根本原因是线程的随机调度,同时在代码结构上也与多个线程同时对同一个对象举行修改有关;
那么既然题目出现了,我们就要想办法解决它!
2. 如何解决线程安全题目

对于线程安全题目,我们常规的解决方案便是-加锁

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表