首页 > 其他分享 >单核多线程可见性问题

单核多线程可见性问题

时间:2022-10-22 14:31:14浏览次数:58  
标签:单核 Thread 可见 start thread 线程 new 多线程 public

背景 学习群上有个同学提出问题,如下截图 image.png image.png

这里可以看到分歧点,我认为JMM协议规定了工作内存,那么即使是单核,JAVA虚拟机也会保证线程本地内存变量的私有性,所以会存在不可见。但是别的同学认为服务器算法本身在单核情况下使用同一个缓存,所以应该是可见的。 实践出真知,所以我写了个demo,使用VM配置了个单核虚拟机去做实验。代码如下 com.czl.thread.TicketThreadTest

package com.czl.thread;


public class TicketThreadTest implements Runnable {


  private int tickets = 100;
  String str = new String("");


  @Override
  public void run() {
    while (true) {
//       synchronized(str) {
      if (tickets > 0) {
        try {
          // 让线程睡眠10毫秒再往下执行(人为放大线程不安全的现象)
          Thread.sleep(10);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }


        System.out.println(Thread.currentThread().getName() + " is saling ticket " + tickets--);
      } else {
        break;
      }
//       }
    }


  }


}

com.czl.thread.ThreadDemo1

package com.czl.thread;


/**
* 这个例子能看出高并发时,会出现票超卖的情况(出售大于库存)
*/
public class ThreadDemo1 {


   /**
    * @param args
    */
   public static void main(String[] args) {
//    new TestThread().run();
//    new TestThread2().start();
      TicketThreadTest t = new TicketThreadTest();
      new Thread(t).start();
      new Thread(t).start();
      new Thread(t).start();
      new Thread(t).start();
//    while (true) {
//       System.out.println(Thread.currentThread().getName() + "** is running!");
//    }


   }


}

运行结果如下图 image.png image.png

虽然最终还是超了100,存在线程安全问题,但是确实是可见的。从日志中不难看出,ticket-1都有被其它线程感知的,所以没有出现重复ticket号码的情况。那为什么超过了100呢?这应该是指令重排导致的。这个讨论给我扫了个盲点,挺有意义的,所以记录下

标签:单核,Thread,可见,start,thread,线程,new,多线程,public
From: https://blog.51cto.com/u_15565709/5785828

相关文章

  • 3_linux多线程
    3_linux多线程编程基本概念程序执行的最小单位进程是线程的容器,不是基本执行单位,是线程容器线程是进程中的不同执行路径,有独立的堆栈、局部变量(因为线程需要线程函数)......
  • Java多线程(1):线程生命周期
    您好,我是湘王,这是我的博客园,欢迎您来,欢迎您再来~ 从事Java开发这些年来,如果要问我Java当中最难的部分是什么?最有意思的部分是什么?最多人讨论的部分是什么?那我会毫不犹豫......
  • 多线程基础知识
    【单核处理器和多核处理器的多线程】单核处理器:为每个线程分配时间片。来模拟并发多核处理器:一核一线程,真正实现并发 【标志】线程一致性,IsAlive就为true,否则为fals......
  • 多线程技术总结
    csdn上笔记也多,但是用的不多,不用就忘了。博客线程笔记——技术笔记:.Net全套就业班视频教程在多线程中的跨线程的方法调用就得用委托。一个进程的多个线程间可相互......
  • Java多线程实现的四种方式
    实现多线程有以下四种方式实现多线程有以下四种方式:1.继承Thread类2.实现Runnable接口3.实现Callable接口4.线程池:提供了一个线程队列,队列中保存着所有等待状态的线程......
  • Java 多线程编程之八:多线程的调度
        本博客是“Java多线程编程”系列的后续篇。“Java多线程编程”系列其他博客请参阅本博客结尾部分。    有多个线程,如何控制......
  • Java 多线程编程之一 进程与线程,并发和并行的区别:吃馒头的比喻
    进程与线程,并发和并行的区别:吃馒头的比喻 没有线程编程的程序好比一个人一只手干活,而多线程的程序就比一个人多之手干活.进程是系统资源分配的独立单位,而线程是可调度......
  • 进程、线程和多线程
    进程间通讯(IPC):管道、信号量、共享内存、消息队列、套接字管道:有名无名(有名无名的区别),在内存中写入,通讯方式:半双工信号量:特殊变量(一般取值大于等于0)例如0、1代表资源状......
  • java中的多线程的常用方法
    java中的多线程的常用方法/*Java中Thread(线程)中的常用方法。1.start():用来启动当前线程,调用当前线程的run()2.run():通常需要重写Thread中的此方法,将创建的线程......
  • 多线程
    多线程概念:Windows操作系统是多任务操作系统,它以进程为单位。每个独立执行的程序被称为一个进程,而每个进程又包含多个线程。系统可以分配给每个进程一段使用CPU的时间(CPU......