线程安全问题

╰半橙微兮° 2021-09-24 02:46 564阅读 0赞

a++造成运行结果错误

在这里插入图片描述

原因分析:

首先我们有两个线程,在做i++的时候,看似是一条语句,实际上是三个步骤在执行。假设最开始 i 的值是1,理论估计在经过两个线程之后,i 的值应该为3。但是实际上结果是2,那么具体的流程是怎样的呢 ?第一个线程在拿到1之后把它加了,但是并没有立刻把它写进去,导致第二个线程在拿的时候,由于第一个线程的值虽然计算完毕了,但是没有告诉任何人,因此第二个线程拿到的还是1,于是呢它就把拿到的1再去加1。此时我们的线程又切回到1,这个时候线程1对于线程2 的内容是一概不知的,它就执行刚才未完的步骤,于是它就把2写回去了 ,而此时一旦切换到线程2,线程2也对与线程1的操作也是一概不知的,所以他也把2写回去。所以这就使得原本等于3的数字等于2。(结合上图理解)

实现死锁

  1. package deadlock;
  2. /** * 描述: 必定发生死锁的情况 */
  3. public class MustDeadLock implements Runnable {
  4. int flag = 1;
  5. static Object o1 = new Object();
  6. static Object o2 = new Object(); public static void main(String[] args) {
  7. MustDeadLock r1 = new MustDeadLock();
  8. MustDeadLock r2 = new MustDeadLock();
  9. r1.flag = 1;
  10. r2.flag = 0;
  11. Thread t1 = new Thread(r1);
  12. Thread t2 = new Thread(r2);
  13. t1.start();
  14. t2.start();
  15. }
  16. @Override public void run() {
  17. System.out.println("flag = " + flag); if (flag == 1) {
  18. synchronized (o1) {
  19. try {
  20. Thread.sleep(500);
  21. } catch (InterruptedException e) {
  22. e.printStackTrace();
  23. }
  24. synchronized (o2) {
  25. System.out.println("线程1成功拿到两把锁");
  26. }
  27. }
  28. }
  29. if (flag == 0) {
  30. synchronized (o2) {
  31. try {
  32. Thread.sleep(500);
  33. } catch (InterruptedException e) {
  34. e.printStackTrace();
  35. }
  36. synchronized (o1) {
  37. System.out.println("线程2成功拿到两把锁");
  38. }
  39. }
  40. }
  41. }
  42. }

发表评论

表情:
评论列表 (有 0 条评论,564人围观)

还没有评论,来说两句吧...

相关阅读

    相关 线安全问题

    我们把⼀段代码想象成⼀个房间,每个线程就是要进⼊这个房间的⼈。如果没有任何机制保证,A进⼊房间之后,还没有出来;B 是不是也可以进⼊房间,打断 A 在房间⾥的隐私。这个就...

    相关 线安全问题

    一、线程安全 VS 线程不安全? 线程安全指的是代码若是串行执行和并发执行的结果完全一致,就称为该代码是线程安全的。 若多个线程串行执行(单线程执行)的结果和并发执行的

    相关 线安全问题

    定义 > 首先大家需要思考一下何为线程安全性呢??? 《Java并发编程实战》书中给出定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替

    相关 线安全问题

    线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污