gpt4 book ai didi

java - 为什么这个同步不起作用?

转载 作者:行者123 更新时间:2023-12-01 18:23:10 26 4
gpt4 key购买 nike

这是我的代码:

public class TestClass {
public static void main(String[] args) throws Exception {
Thread threadOne = new Thread(new SomeRunnable("x"));
Thread threadTwo = new Thread(new SomeRunnable("y"));
threadOne.start();
threadTwo.start();
}
}

public class SomeRunnable implements Runnable {
private String name;
public SomeRunnable(String name) {
this.name = name;
}
@Override
public void run() {
for(int i=0;i<50;i++) {
NameShouter.shoutName(name);
}
}
}

public class NameShouter {
public static void shoutName(String name) {
synchronized (System.out) {
System.out.print(name);
}
}
}

我将得到的输出是:

xxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

我期望 System.out 会同步,但事实并非如此。为什么?我怎样才能让这段代码工作并输出:

xxxxxxxxxxx....yyyyyyyy....

最佳答案

您正在同步 shoutName 的每一次调用,这仅意味着每个名称都完全写在下一个名称之前。如果你想依次喊出所有相同的名字,你需要在循环中移动synchronized:

public class SomeRunnable implements Runnable {
private String name;
public SomeRunnable(String name) {
this.name = name;
}
@Override
public void run() {
synchronized (System.out) {
for(int i=0;i<50;i++) {
NameShouter.shoutName(name);
}
}
}
}

public class NameShouter {
public static void shoutName(String name) {
System.out.print(name);
}
}

由于您提到您可能有不同的 NameShouter 来从不同的事物中喊出(并且您仍然需要能够喊出这些名字 50 次),因此您可以引入一个方法重载来喊出一个数字次数并传递 PrintStream 用作参数:

public static void shoutName(String name, int count, PrintStream out) {
synchronized (out) {
out.print(name);
}
}

然后您只需调用 shoutName("x", 50, System.out) 即可了解您当前的行为。

随着时间的推移,您会注意到,静态方法会让事情变得很麻烦,不过,您可以只使用 NameShouter 对象,这些对象具有适合它们所调用的资源的属性以及其他任何内容必要的。

如果您的资源不仅仅是一个 PrintStream,例如如果你也想对图像喊出名字,也许,那么要么将你想要喊出的任何其他内容包装在 PrintStream 中(可能不是最好的主意,因为在某些事情上滥用接口(interface)会使事情变得有些困难来实现),或者创建您自己的接口(interface),例如

public interface IResource {
void print();
}

并将 System.out 以及您正在使用的其他任何内容包装到 IResource 中。

关于java - 为什么这个同步不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27075667/

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