- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
如果有一个同步块(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/
在 java 中不使用“同步”关键字的情况下,是否有其他方法可以同步类或方法? 谢谢, 马利卡琼·科卡塔努尔 最佳答案 您可能想查看并发包中引入的对 JDK 5 的更改。 http://java.su
第 1 部分: 假设下面这段代码 void method1(){ synchronized (lockObject){ method2(); System.ou
我有一个 REST 服务器和一个在移动设备上运行的客户端应用程序。客户端有一些数据并希望从服务器获取数据更新。如何以 RESTful 方式在单个事务中执行此操作? 假设客户有以下元素: widge
我有一个多线程 Java 应用程序。在一种方法中,需要同步一个 ArrayList。由于 arrayList 不是线程安全的,所以我必须使用同步。问题是 ArrayList 类型的对象不是对象的成员变
我正在阅读 Android 示例中的 BluetoothChatService.java 文件,有一件事特别让我感到困惑。 方法在多个位置访问静态成员,并且定义为同步。 在另一部分中,正在访问同一个静
我知道为了实现线程安全和同步,我们使用同步块(synchronized block)或方法。 但我无法理解声明- “Java 中的同步块(synchronized block)在某些对象上同步 ” 任
在 Scala 中使用 JDBC 的示例中,有以下代码: this.synchronized { if (!driverLoaded) loadDriver() } 为什么this.synchro
abstract class A { protected abstract int isRunning(); public void concreteMethod() { synchr
有谁可以分享一下他们的经验吗?“我们什么时候在同步方法和同步块(synchronized block)之间进行调用”有任何性能问题吗? 最佳答案 When do we make a call to u
这是我之前问题的后续问题,Is this variable being safely accessed by using synchronization? 对于下面的程序, Class SubClas
我目前正在为 N 体问题实现多线程版本的 Barnes-Hut 算法。虽然该算法有效,但它不是很优化,我正在尝试减少我的程序的运行时间。 我已经确保有多个线程可以准确地找到我正在使用的空间的边界,并意
我有这门课: public class MyClass { public MyClass(){} public void actionA(){ synchronized
又是一个关于ArrayList和synchronize的问题。 我只想知道这段代码到底做了什么: ArrayList list = ....; synchronized (list) { if
我可以在另一个同步块(synchronized block)中包含同步块(synchronized block)以同步另一个对象吗? 例子: synchronized(myObjetc1){
public class ObjectCounter { private static long numOfInstances = 0; public ObjectCounter(){
我在某处读到,对于 various reasons 应该避免 synchronized(this) .然而,我遇到的一些值得尊敬的代码在构造函数中使用了以下内容: public SomeClass(C
Java 为同步代码的关键部分提供了一种非常方便的习惯用法: synchronized(someObject) { // do something really important all b
我有一个 WeakReference 的 Collections.synchronizedList,_components; 我写了类似下面的内容,希望编译者会提示: public boolean a
使用下面两个版本的Singleton Classes有什么区别 首先我使用的是synchronized(Singleton.class) 在第二个我使用同步(Obj)//第一种类型 公共(public
我正在查看 DatagramSocket 的源代码,我发现了这个: public void disconnect() { synchronized (this) { if (i
我是一名优秀的程序员,十分优秀!