gpt4 book ai didi

java - 如果可以通过任何其他方法访问对象,那么在同步块(synchronized block)中锁定对象有什么用呢?

转载 作者:行者123 更新时间:2023-11-30 03:50:07 26 4
gpt4 key购买 nike

如果有一个同步块(synchronized block)正在锁定一个对象,比如 StringBuilder sb,其中一个线程正在执行该同步块(synchronized block),其中 sb 被锁定,假设有另一个线程正在调用另一个方法,该方法将尝试更改sb 的值(不在同步块(synchronized block)中),那么,是否允许这样做?

public static void main(String[] args) {
A a = new A();
new Thread(new MyRunnable(a), "T1").start();
new Thread(new MyRunnable(a), "T2").start();
}

static class MyRunnable implements Runnable {
A a;

public MyRunnable(A a) {
super();
this.a = a;
}

@Override
public void run() {
while (true) {
if ("T1".equals(Thread.currentThread().getName())) {
a.m1();
} else {
a.m2();
}
}
}
}


static class A {

StringBuilder abc = new StringBuilder("fdfd");

public void m1() {

synchronized (abc)
{

System.out.println("abc locked : " + abc);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();}
System.out.println("abc released: " + abc);
}

}

public void m2() {
System.out
.println(Thread.currentThread().getName() + " running");

System.out.println("trying to access abc");
abc.append("A");
System.out.println("abc accessed");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();}
}
}

}

我认为锁定一个对象将不允许更改该对象以及被修改或访问。但是,从输出中我看到锁定的对象可以修改:

输出:

    abc locked : fdfd
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc accessed
T2 running
trying to access abc
abc released: fdfdAA
abc accessed
abc locked : fdfdAAA
T2 running

我不明白这一点,有人可以解释一下吗?锁定一个对象有什么用?仅仅是因为 wait/notify/notifyAll 方法吗?

最佳答案

If there is a synchronized block which is taking lock on an object, say StringBuilder sb, which one thread is executing this synchronized block in which sb is locked, suppose there is another thread which is calling another method which will try to change the value of sb(not in synchronized block), then, will it be allowed to do that?

呃是的。我认为您需要阅读一些有关 synchronized 的作用的内容。请参阅Java tutorial 。它不会“锁定”对象,因为限制其他线程对其进行操作。它的作用是为锁定同一对象实例的线程的包围代码块提供互斥锁。对象中的字段完全可以在 synchronized block 内部或外部发生变化。

常量对象上同步总是一个好主意,所以我倾向于这样做:

 private final Object lock = new Object();
...
synchronized (lock) {
// only one thread allowed inside this block at a time
}

如果多个线程正在访问某种线程不安全的对象,我将同步该对象并在 synchronized block 内对该对象执行操作:

 private final SomeUnsafeObject someObject = ...;
...
synchronized (someObject) {
// only one thread allowed inside this block at a time
someObject.someUnsafeMethodCall(...);
}
// no accesses (read or write) outside of the synchronized block

I thought locking an object would not allow to change that object as well from being modified or accessed. But, from output I am seeing the locked object can be modified:

不,不会隐式阻止正在更改的对象。如果您只访问 synchronized block 内部的对象字段,那么您就已经完成了您想要的操作。

public void m2() {
...
abc.append("A");

正确,由于您不在此处的 synchronized (abc) block 内,因此没有任何东西可以阻止线程调用 abc.append(...) .

I am not getting this, can anybody please explain this. What is the use of taking a lock on an object? Is it just because wait/notify/notifyAll methods?

同步允许您根据锁定对象(或者准确地说是该对象上的监视器)一次控制一个线程对代码块的访问。它还允许您执行 lock.wait(...) 和 lock.notify(...) 来控制线程操作并阻止/释放它们。

同步还设置内存屏障,以便线程在进入同步块(synchronized block)时将看到存储到中央内存的更改,并在离开同步块(synchronized block)时看到写入中央内存的更改。如果没有这些内存屏障,如果其他线程在没有同步的情况下访问 StringBuilder,那么它们可能看起来是该类的部分更新部分,这可能会导致 NPE 或其他故障。

关于java - 如果可以通过任何其他方法访问对象,那么在同步块(synchronized block)中锁定对象有什么用呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24669124/

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