我对 synchronized
关键字的用法和意义有一些疑问。
synchronized
关键字的意义是什么?- 什么时候方法应该是
synchronized
? - 它在编程和逻辑上意味着什么?
原文由 Johanna 发布,翻译遵循 CC BY-SA 4.0 许可协议
我对 synchronized
关键字的用法和意义有一些疑问。
synchronized
关键字的意义是什么?synchronized
?原文由 Johanna 发布,翻译遵循 CC BY-SA 4.0 许可协议
好吧,我认为我们已经有足够的理论解释,所以考虑一下这段代码
public class SOP {
public static void print(String s) {
System.out.println(s+"\n");
}
}
public class TestThread extends Thread {
String name;
TheDemo theDemo;
public TestThread(String name,TheDemo theDemo) {
this.theDemo = theDemo;
this.name = name;
start();
}
@Override
public void run() {
theDemo.test(name);
}
}
public class TheDemo {
public synchronized void test(String name) {
for(int i=0;i<10;i++) {
SOP.print(name + " :: "+i);
try{
Thread.sleep(500);
} catch (Exception e) {
SOP.print(e.getMessage());
}
}
}
public static void main(String[] args) {
TheDemo theDemo = new TheDemo();
new TestThread("THREAD 1",theDemo);
new TestThread("THREAD 2",theDemo);
new TestThread("THREAD 3",theDemo);
}
}
注意: synchronized
只要前一个线程的执行没有完成,就会阻塞下一个线程对方法test()的调用。线程可以一次访问一个方法。没有 synchronized
所有线程都可以同时访问这个方法。
当一个线程调用对象的同步方法’test’时(这里对象是’TheDemo’类的一个实例)它获取该对象的锁,任何新线程都不能调用同一个对象的任何同步方法,只要前一个线程已经获得锁的不释放锁。
当调用该类的任何静态同步方法时,都会发生类似的事情。线程获取与该类关联的锁(在这种情况下,任何线程都可以调用该类实例的任何非静态同步方法,因为该对象级锁仍然可用)。只要当前持有锁的线程未释放类级锁,任何其他线程将无法调用类的任何静态同步方法。
同步输出
THREAD 1 :: 0
THREAD 1 :: 1
THREAD 1 :: 2
THREAD 1 :: 3
THREAD 1 :: 4
THREAD 1 :: 5
THREAD 1 :: 6
THREAD 1 :: 7
THREAD 1 :: 8
THREAD 1 :: 9
THREAD 3 :: 0
THREAD 3 :: 1
THREAD 3 :: 2
THREAD 3 :: 3
THREAD 3 :: 4
THREAD 3 :: 5
THREAD 3 :: 6
THREAD 3 :: 7
THREAD 3 :: 8
THREAD 3 :: 9
THREAD 2 :: 0
THREAD 2 :: 1
THREAD 2 :: 2
THREAD 2 :: 3
THREAD 2 :: 4
THREAD 2 :: 5
THREAD 2 :: 6
THREAD 2 :: 7
THREAD 2 :: 8
THREAD 2 :: 9
没有同步的输出
THREAD 1 :: 0
THREAD 2 :: 0
THREAD 3 :: 0
THREAD 1 :: 1
THREAD 2 :: 1
THREAD 3 :: 1
THREAD 1 :: 2
THREAD 2 :: 2
THREAD 3 :: 2
THREAD 1 :: 3
THREAD 2 :: 3
THREAD 3 :: 3
THREAD 1 :: 4
THREAD 2 :: 4
THREAD 3 :: 4
THREAD 1 :: 5
THREAD 2 :: 5
THREAD 3 :: 5
THREAD 1 :: 6
THREAD 2 :: 6
THREAD 3 :: 6
THREAD 1 :: 7
THREAD 2 :: 7
THREAD 3 :: 7
THREAD 1 :: 8
THREAD 2 :: 8
THREAD 3 :: 8
THREAD 1 :: 9
THREAD 2 :: 9
THREAD 3 :: 9
原文由 Dheeraj Sachan 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
3 回答1.7k 阅读✓ 已解决
synchronized
关键字是关于不同线程读取和写入相同变量、对象和资源的。这在 Java 中不是一个微不足道的话题,但这里引用 Sun 的话:简而言之: 当您有两个线程正在读取和写入同一个“资源”时,比如一个名为
foo
的变量,您需要确保这些线程以原子方式访问该变量方法。如果没有synchronized
关键字,您的线程 1 可能看不到线程 2 对foo
所做的更改,或者更糟的是,它可能只更改了一半。这不是您逻辑上期望的。同样,这是 Java 中的一个重要主题。要了解更多信息,请在此处探索有关 SO 和 Interwebs 的主题:
继续探索这些主题,直到 “Brian Goetz” 这个名字在您的大脑中永久地与术语 “并发” 相关联。