gpt4 book ai didi

java - 扩展 Thread 类时无法同步两个线程,但在实现 Runnable 接口(interface)时可以工作

转载 作者:行者123 更新时间:2023-11-29 04:56:36 24 4
gpt4 key购买 nike

这里同步块(synchronized block)不工作:

class NewThreadt extends Thread {
synchronized void dota(){
for(int i = 5; i > 0; i--)
{
System.out.println(i);
try {
Thread.sleep(500);

} catch (InterruptedException e) {
System.out.println("Child interrupted.");
}
}

}

// This is the entry point for the second thread.
public void run() {
dota() ;
System.out.println("Exiting child thread.");
System.out.println(Thread.currentThread()); //gives the name of thread

}
}

class trial {
public static void main(String args[]) {
NewThreadt t=new NewThreadt();
NewThreadt q=new NewThreadt();
t.start();
q.start(); both are in main


System.out.println("Main thread exiting.");
}
}

输出:

Main thread exiting.
5
5
4
4
3
3
2
2
1
1

但是当我进行以下更改时,同步块(synchronized block)会起作用:

class NewThreadt implements Runnable  //instead of class NewThreadt extends Thread 

NewThreadt abc=new NewThreadt(); //Changes in main()
Thread t=new Thread(abc);
Thread q=new Thread(abc);
t.start();
q.start();

输出:

Main thread exiting.
5
4
3
2
1
5
4
3
2
1

为什么会这样?这两个示例的工作方式不应该相同吗?

最佳答案

同步依赖于共享一个公用锁。实例方法上的 synchronized 关键字意味着要让线程进入该方法,它首先必须获取 this 上的锁。

在你的第一个例子中没有共享锁,两个线程中的每一个都在锁定自己。每个线程都获取自己的锁并且没有人阻塞,两个线程并发运行。 (这里唯一的锁定是,当一个线程想要写入控制台时,它必须首先获取控制台的锁,以便每个 println 以原子方式发生。)

在第二个示例中,相同的 Runnable 被传递到每个线程,因此它们都锁定在同一个对象上,即 Runnable。一个线程获取锁并执行,另一个必须等​​待第一个线程释放锁。

如果你改变第二个例子给每个线程一个单独的Runnable:

Thread t=new Thread(new NewThreadt());    
Thread q=new Thread(new NewThreadt());
t.start();
q.start();

然后您会看到同步不起作用,它的行为与第一个示例类似。

关于java - 扩展 Thread 类时无法同步两个线程,但在实现 Runnable 接口(interface)时可以工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33559280/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com