Java 多线程代码行为
Posted
技术标签:
【中文标题】Java 多线程代码行为【英文标题】:Java Multithread code behavior 【发布时间】:2017-11-21 09:21:51 【问题描述】:对于下面的java代码:
public class Chess implements Runnable
public void run()
move(Thread.currentThread().getId());
void move(long id)
System.out.print(id + " ");
System.out.print(id + " ");
public static void main(String[] args)
Chess ch = new Chess();
new Thread(ch).start();
new Thread(new Chess()).start();
此代码的一个可能结果是 - 输出可能是 4 2 4 2(或者是 4、2 以外的其他线程 ID)。有人可以解释一下这是怎么可能的吗?鉴于线程将在“Chess”类的不同实例上运行,我们如何在此处打印不同的 id,因为两个 S.O.P 语句都立即打印 id,并且只有这两个线程会调用 move 方法
【问题讨论】:
我不明白你的问题。您启动了两个线程,每个线程都打印其 ID 两次,您想知道这两个 ID 中的每一个都可能打印两次吗? 输出可能是因为来自两个线程的System.out.print
语句可能交错。
尝试给线程名称,以便您理解。我相信正如安迪·特纳所说,线程交错运行。所以线程 ID: 4 执行,并且在 move() 完成之前,线程 id:2 执行。
您的 main() 例程创建了两个新的 Thread
实例。 Thread
类的构造函数保证每个实例都有自己的唯一 ID。 Thread.currentThread()
返回对运行调用它的代码的Thread
实例的引用。因此,调用Thread.currentThread().getId()
的两个不同线程会得到两个不同的数字也就不足为奇了。
【参考方案1】:
这并不奇怪。
您正在创建两个线程,每个线程都有不同的 id(在您的情况下分别为 2 和 4)。您将这些 id 打印两次,因此每个 id 都会打印两次。
现在解释不同的数字及其出现。
那么订单呢?好吧,这就是线程的问题,它们由处理器执行,您无法控制每条处理器指令的执行顺序。
PS:Chess
实例的数量无关紧要。如果您应该将代码更改为:
Chess ch = new Chess();
new Thread(ch).start();
new Thread(ch).start();
没关系。
【讨论】:
【参考方案2】:“主”线程始终运行用户创建的线程。在您的情况下,“主”线程负责运行, new Thread(ch).start() //线程 - 0 新线程(新国际象棋()).start(); //线程 - 1.
由于上述线程具有相同的优先级(默认为 5),ThreadScehduler 将调度两个线程同时运行。因此,您会得到两个不同线程的 ID。
您可以在 Chess 类上同步并运行线程,然后您将一次打印一个线程 ID。
您可以按如下方式应用类级别锁定,并一次打印一个 ID,
public class Chess implements Runnable
public void run()
move(Thread.currentThread().getId());
synchronized static void move(long id)
System.out.println(id + " ");
System.out.println(id + " ");
public static void main(String[] args)
Chess ch = new Chess();
new Thread(ch).start();
new Thread(new Chess()).start();
【讨论】:
以上是关于Java 多线程代码行为的主要内容,如果未能解决你的问题,请参考以下文章