lui*_*7up 5 java multithreading thread-safety
好吧,我知道很难理解线程是如何工作的,但是直到有人帮助我理解我会相信它是一个bug :)
在我的Main类及其main()方法中,我有:
public static void main(String args[]){
StoneBucket stoneBucket = new StoneBucket();
StonePutter spRunnable = new StonePutter(stoneBucket);
StoneThrower stRunnable = new StoneThrower(stoneBucket);
StoneThrower stRunnable2 = new StoneThrower(stoneBucket);
//Create the Threads that will take the Runnables as arguments
Thread puttingThread = new Thread(spRunnable);
Thread throwingThread = new Thread(stRunnable);
Thread throwingThread2 = new Thread(stRunnable);
puttingThread.setName("Putter");
throwingThread.setName("Thrower 1");
throwingThread2.setName("Thrower 2");
[...]
Run Code Online (Sandbox Code Playgroud)
然后在我的StoneThrower课程中
public class StoneThrower implements Runnable{
private StoneBucket sb;
private String name;
public StoneThrower(StoneBucket _sb){
this.sb = _sb;
}
public void run(){
name = Thread.currentThread().getName();
System.out.println("T::"+name+" started...");
int count = 0;
while(true){
[...]
Run Code Online (Sandbox Code Playgroud)
当我编译并运行此代码时,我得到:

所以,我的问题是为什么这两个线程都返回相同的名称currentThread().getName()?当它们被创建时,它们被分配了名称,threadX.setName("XXX")并且通过调用启动了那些可运行的threadX.start()...有人可以澄清一下这个吗?
编辑:我接受了正确的答案,因为将stRunnable更改为stRunnable2的行为是预期的.现在真正的问题是为什么会发生这种情况.我创建两个线程并分别启动它们.如何运行run()方法(在创建线程时调用一次)返回错误的名称?
这是因为您将线程名称存储在name您的实例变量中StoneThrower.由于并发性,第二个线程会覆盖name第一个线程刚刚设置的值,并且它们都输出相同的值.
这是你的场景:
1. Thread1#start
2. Thread2#start
3. Thread1#runnable#run -> runnable.name = 'Thrower 1'
4. Thread2#runnable#run -> runnable.name = 'Thrower 2' // overrides
5. Thread1#runnable#run -> System.out.println(runnable.name)
6. Thread2#runnable#run -> System.out.println(runnable.name)
Run Code Online (Sandbox Code Playgroud)
您使用相同的runnable创建两个线程:
Thread throwingThread = new Thread(stRunnable);
Thread throwingThread2 = new Thread(stRunnable);
^^^^^^^^^^ stRunnable2?
Run Code Online (Sandbox Code Playgroud)
将线程名称存储在Runnable对象的实例变量中.由于该对象由两个线程共享,因此要执行的第二个线程将name = Thread.currentThread().getName()使用自己的名称覆盖第一个线程的名称.