gpt4 book ai didi

java - 试图掌握Java中的基本线程同步

转载 作者:行者123 更新时间:2023-11-29 07:45:09 24 4
gpt4 key购买 nike

public class ThreadTest implements Runnable {

private int counter;
private Date mydate = new Date();

public void upCounter1() {
synchronized (mydate ) {
for (int i = 0; i < 5; i++) {
counter++;
System.out.println("1 " + counter);
}
}

}

public void upCounter2() {
synchronized (mydate ) {
for (int i = 0; i < 5; i++) {
counter++;
System.out.println("2 " + counter);
}
}
}

public void upCounter3() {
synchronized (mydate ) {
for (int i = 0; i < 5; i++) {
counter++;
System.out.println("3 " + counter);
}
}
}

@Override
public void run() {
upCounter1();
upCounter2();
upCounter3();
}

public static void main(String[] args) {
Threadtest mtt = new Threadtest();
Thread t1 = new Thread(mtt);

Thread t2 = new Thread(mtt);

Thread t3 = new Thread(mtt);

t1.start();
t2.start();
t3.start();
}

}

我用各种同步技术尝试了这段代码,我想确保我了解正在发生的事情。我已经阅读了很多这方面的文章,但没有一篇对我来说足够详细。

所以这是我观察到的:

  1. synchronized (this):这仅在我为所有线程提供相同的 Threadtest 实例时有效,因为如果我为每个线程提供其自己的实例,每个线程都将获得该实例的内在锁定并可以在不中断其他线程的情况下访问这些方法。

  2. 但是,如果我给每个线程它自己的实例,我可以这样做:synchronised (getClass()),因为这样我就得到了类的内部锁

  3. 或者,我可以这样做:synchronized (mydate),其中适用于 synchronized (this) 的相同规则。但它的优点是不公开。 > 我真的不明白这一点。使用this有什么“危险”?

  4. 除了synchronized (getClass()),我还可以使用私有(private)静态字段。但是,我不能执行 synchronized(Date.class)

  5. 我可以同步整个方法(与同步块(synchronized block)的效果相同)

  6. 使计数器变易变是行不通的,因为递增不是真正的原子操作

  7. 如果我想让每个方法都可以单独访问,我会创建三个私有(private)字段并在同步块(synchronized block)中使用它们。然后,我有效地使用了这些字段的内部锁,而不是我的类或实例的内部锁。

  8. 我还注意到,当我使用类锁时,每个方法都被视为独立的,我实际上有 3 个计数器,计数器变为 15。如果我使用实例锁,计数器变为 45。是吗正确和预期的行为?

我的解释和观察是否正确? (我基本上想确保我从我得到的控制台输出中得出正确的结论)

最佳答案

a-c; e-f 是正确的。

c) Alternatively, I could do: synchronised (mydate), where the same rules apply that apply to synchronised (this). But it has the advantage of not being public. > I dont really understand this. What is the "danger" of using this?

论点是其他代码也可能决定将该对象用作锁。这可能会引起冲突;当您知道情况永远不会如此时,那么它就不是一件坏事。当在他们的代码中使用 wait/notify 时,这通常也是一个更严重的问题。

d) Alternatively to synchronised (getClass()), I could also use a private static field. However, I cannot do synchronised(Date.class).

你可以使用 Date.class,它只是有点奇怪,并且属于上面 c 中讨论的关于不污染其他类工作空间的论点。

g) If I want to make each method accessible individually, I would make three private fields and use them in the synchronised-blocks. I then am effectively using the intrinsic locks of those fields and not of my class or instance.

鉴于这三个方法共享相同的状态,那么不,这不是明智的,因为它会导致线程之间的竞争。

h) I also noted that when I use the class-lock, each method is viewed as separate and I have effectively 3 counters that go to 15. If I use the instance lock, the counter goes to 45. Is that the correct and expected behaviour?

不,这听起来不对,但我可能误解了你。当使用 this 或 this.getClass() 作为锁时,我希望在这两种情况下总数为 45。

关于java - 试图掌握Java中的基本线程同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26512515/

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