“Java线程计数器”;问题;?

“Java线程计数器”;问题;?,java,multithreading,java-8,Java,Multithreading,Java 8,我在尝试线程优先级的影响,当运行方法中的println停留在注释中时,两个线程同时结束,我不理解这种行为,您能解释一下吗?多谢各位 主类 测试类 您的两个线程在没有正确同步的情况下访问共享可变变量。在本例中,无法保证一个线程何时(或是否)了解到另一个线程所做的更改。在您的情况下,一个线程所做的更改根本不会被另一个线程注意到。请注意,对于基本数据类型(如boolean),不读取最新值是可能发生的最糟糕情况,而对于非基本数据类型,则可能会出现更糟糕的问题,即结果不一致 插入print语句会产生同步

我在尝试线程优先级的影响,当运行方法中的println停留在注释中时,两个线程同时结束,我不理解这种行为,您能解释一下吗?多谢各位

主类
测试类
您的两个线程在没有正确同步的情况下访问共享可变变量。在本例中,无法保证一个线程何时(或是否)了解到另一个线程所做的更改。在您的情况下,一个线程所做的更改根本不会被另一个线程注意到。请注意,对于基本数据类型(如
boolean
),不读取最新值是可能发生的最糟糕情况,而对于非基本数据类型,则可能会出现更糟糕的问题,即结果不一致

插入print语句会产生同步线程的副作用,因为
PrintStream
执行内部同步。由于无法保证
System.out
将包含这样一个同步打印流实现,因此这是一个特定于实现的副作用

如果将
stop
的声明更改为

static volatile boolean stop = false;
线程将在每次迭代中从共享堆中重新读取值,并立即对更改作出反应,以降低总体性能为代价


请注意,仍然不能保证此代码按预期工作,因为既不能保证线程优先级有任何影响,也不能保证线程完全并行运行。线程调度是依赖于实现和环境的行为。例如,您可能会发现,不是优先级最高的线程首先完成循环,而是碰巧最先启动的线程。

为了澄清:在任何操作系统的任何语言环境中,线程/进程“优先级”的唯一目的是向操作系统建议“我认为,这两个线程中的哪一个应该首先运行”如果两者都是即时“可运行”的,则必须选择只运行其中一个

(根据我的经验,在实践中最好的例子是Unix/Linux
nice
命令,它自动地将命令的执行优先级降低了相当大的一部分。)执行很少I/O的CPU密集型工作负载实际上可以从降低优先级中获益


正如其他回答者已经强调的那样,不可能预测“实际会发生什么”,优先级永远不能用来改变这一前提。您必须显式地使用适当的同步原语,以确保代码在所有情况下都能正确执行。

您预期的行为是什么?你的计算机有多少核?你认为线程优先级是什么?你所说的“两个线程同时结束”是什么意思?您不了解这种行为的原因是什么?您的输出描述了正确的行为。你还期望什么?我不知道为什么没有打印,它们会在同一时间结束,而当我将打印和计数器一起放入循环时,它们不会结束。我的计算机有2个内核/4个线程。可能是
public class Test implements Runnable{ 
    public Thread thread;
    static boolean stop = false;
    int count = 0;

    public Test(String name){
        thread = new Thread(this, name);
    }

    @Override
    public void run(){

        for(int i = 0; i < 10000000 && stop == false; i++){
            count = i;
            //System.out.println(count + " " + thread.getName());
        }
        stop = true;

        System.out.println("End of " + thread.getName());
    }
}
     without println          with println

    End of Thread #1        End of Thread #1
    End of Thread #2        End of Thread #2
    Thread #1: 9999999      Thread #1: 9999999
    Thread #2: 9999999      Thread #2: 3265646
    End of main thread.     End of main thread.
static volatile boolean stop = false;