将单个runnable对象传递给多个线程构造函数

如果我创建一个可运行的对象

Runnable run = new MyRunnable(); 

然后将同一个确切的对象传递给两个线程构造函数并运行它们

 new Thread(run).start; new Thread(run).start; 
  1. 有可能吗? 有什么影响?
  2. 如果我调用Thread.sleep(0); 在类MyRunnable中,两个线程都会因为它们是同一个对象而睡眠,还是线程实体与对象完全分离?
  3. 是否有理由这样做,如果不是,请仍然回答上面的两个问题,因为我不认为我完全理解线程机制了吗?

  1. 这绝对是可能和合法的。 如果您的Runnable没有状态(没有字段),那么一切都会好的。 如果您的Runnable确实具有可变状态,那么您可能需要使用Java的许多互斥机制,ReentrantLocksynchronized关键字。 因为两个线程都将改变同一个Runnable对象的字段。

  2. 不,你创建并运行了两个不同的线程。 他们只需调用Runnable.run()

  3. 这不是出于可能性的范畴。 我甚至不会说这一定是不好的做法。 你可能会这样做的具体情况留给读者一个练习……

1)可能吗? 有什么影响?

对的,这是可能的。

这意味着Runnable中的任何状态(可能)都被所有线程共享,并且需要正确地同步对该状态的访问/更新。

2)如果我调用Thread.sleep(0); 在类MyRunnable中,两个线程都会因为它们是同一个对象而睡眠,还是线程实体与对象完全分离?

不,他们不会。

Thread在逻辑上与Runnable 。 调用Thread.sleep()不会直接影响Runnable和可能共享它的其他线程。 (它可能会间接影响其他线程;例如,如果一个线程在保持Runnable的原始锁定时hibernate,而其他线程需要获取锁定才能进行。)

3)是否有理由这样做,如果不是,请仍然回答上面的两个问题,因为我不认为我完全理解线程机制了吗?

如果没有与Runnable关联的特定于线程的状态,并且您希望最小化空间开销或初始化Runnable开销,则可以执行此操作。 但是这种用例在实践中很少见。

在绝大多数实际用例中,每个线程都需要一个不同的Runnable实例。