当前位置: 首页 > 知识库问答 >
问题:

为什么不同的运行方法体线程的行为不同?

杨豪
2023-03-14
public class ThreadPractice {
static boolean canrunstatic;

public static void main(String[] args) throws InterruptedException {

    Thread backgroundThread = new Thread(new Runnable() {
        public void run() {
            int i = 0;
            while (!canrunstatic){i++;}
            System.out.println("finished");
        }
    });
    backgroundThread.start();
    TimeUnit.SECONDS.sleep(1);
    canrunstatic = true;
}
System.out.println("im still running");
public class ThreadPractice {
static boolean canrunstatic;


public static void main(String[] args) throws InterruptedException {

    Thread backgroundThread = new Thread(new Runnable() {
        public void run() {
            int i = 0;
            while (!canrunstatic){i++;System.out.println("im still running");}
            System.out.println("finished");
        }
    });
    backgroundThread.start();
    TimeUnit.SECONDS.sleep(1);
    canrunstatic = true;


}

共有1个答案

井轶
2023-03-14

确切地说,它只是不能保证线程会停止,但它确实停止并不是被禁止的。这背后的逻辑是由Java内存模型提供的,这是一个相当复杂的主题,但为了理解Java中的多线程,这是必要的。

其概念是,只有当一个线程的非易失性字段的写入操作相互同步时,另一个线程才需要看到这两个操作。如果执行编译器的线程所表现的行为没有改变,则允许编译器对某些操作重新排序。但另一个线程可能会看到这一点。因此,您需要适当的同步,以便告诉编译器在某些部分不允许重新排序

在这里阅读关于这一点的完整论文:JSR-133

 类似资料:
  • 我使用http://openjdk.java.net/projects/code-tools/jmh/的JMH基准框架对我的代码进行基准测试。我的理解是,JMH在基准测试期间多次分叉JVM,以便丢弃由JVM在执行期间执行的实时(JIT)分析建立的任何概要文件。 我理解为什么这在某些情况下是有用的,比如下面(逐字复制自http://Java-performance . info/jmh/): 默认情

  • 问题内容: 我在同一文件中有以下程序。我已经同步了run()方法。 输出是 我的问题是,为什么同步方法同时允许“我的线程1”和“我的线程4”线程访问? 问题答案: 方法在实例级别工作。 类的每个实例都有自己的锁。每次输入实例的任何方法都将获取该锁。这样可以防止多个线程 在同一个实例上 调用方法(请注意,这还可以防止在同一个实例上调用 不同的 方法)。 现在,由于您有两个类实例,因此每个实例都有自己

  • 问题内容: 我一直认为,在实现Runnable的java类中同步run方法是多余的。 我试图弄清楚为什么人们这样做: 这似乎是多余且不必要的,因为它们正在为另一个线程获取对象的锁。更确切地说,他们明确指出只有一个线程可以访问run()方法。但是由于它是run方法,它本身不是自己的线程吗?因此,只有它可以访问自身,并且不需要单独的锁定机制? 我在网上找到了一个建议,即通过同步运行方法,您可以通过以下

  • 我将介绍Spring Security的不同类实现。我知道我们将身份验证对象设置为SecurityContext ThreadLocal对象,如下所示: 因此,基本上每个线程都有一个单独的SecurityContext ThreadLocal对象副本,它保存该线程的身份验证对象。在这之前都很好。我在安全配置中将SessionCreationPolicy设置为无状态。以下是安全配置: 但是,我不明白

  • 问题内容: 我们可以使用docker拉取不同的图像。而且这些映像是不同的linux发行版。但是,无论运行在哪个linux distro docker上,docker都可以像在虚拟机中一样运行这些不同的linux发行版。 我知道docker使用aufs来控制不同的读写访问级别。因此它可以重用主机上的某些文件。但是当主机运行时,docker如何在容器中运行?图像是否包含二进制文件?但是,不同的Linu

  • 问题内容: 切片是对基础数组的引用。这是有道理的,似乎可以在内置/原始类型上使用,但是为什么不能在结构上使用呢?我假设即使我更新了一个struct字段,引用/地址也仍然相同。 需要说明的是:我知道我可以在两种情况下都使用指针。我只是对为什么不更新结构感兴趣(与int不同)。 问题答案: 调用时要做的是传递一个包含值副本的新数组,并立即丢弃该数组。这与您使用基元不同,因为您保留了数组。 这里有两种方