是“同步的”真的只是语法糖吗?
我是多线程新手,我编写了这段代码,通过同时运行的线程递增并打印变量来打印数字 1-10000。
这是我正在使用的代码:
package threadtest;
public class Main{
static int i=0;
static Object lock=new Object();
private static class Incrementer extends Thread{
@Override
public void run(){
while (true){
synchronized(lock){
if (i>=10000)
break;
i++;
System.out.println(i);
}
}
}
}
public static void main(String[] args) {
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
}
}
这有效 - 我编写了一个测试程序来检查输出,并且打印的数字恰好是 1-10000。
我的问题是这样的:我听说 synchronized
只是语法糖。但如果不使用它,我似乎无法取得成功的结果。我缺少什么?
I am new to multithreading, and I wrote this code which prints the numbers 1-10000 by having concurrently running threads increment and print a variable.
Here's the code I'm using:
package threadtest;
public class Main{
static int i=0;
static Object lock=new Object();
private static class Incrementer extends Thread{
@Override
public void run(){
while (true){
synchronized(lock){
if (i>=10000)
break;
i++;
System.out.println(i);
}
}
}
}
public static void main(String[] args) {
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
new Incrementer().start();
}
}
This works - I wrote up a test program to check the output, and the numbers printed are exactly 1-10000 in order.
My question is this: I've heard that synchronized
is only syntactic sugar. But I can't seem to achieve a successful result without using it. What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
synchronized
绝不是任何东西的语法糖。如果不使用synchronized
关键字,就无法在 Java 中使用锁。Java 中的锁存在某种“语法糖”,即
synchronized
既可以应用于块(正如您上面所做的那样),也可以应用于整个方法。以下两种方法在语义上大致相同:那么为什么要执行第二个版本而不是第一个版本呢?
this
用于锁定,这为您提供了更灵活的锁定语义。synchronized
is by no means syntactic sugar for anything. There is no way to work locks in Java without using thesynchronized
keyword.Where there is "syntactic sugar" of a sort in locks in Java is that
synchronized
can apply both to blocks (as you've done it above) and to whole methods. The following two methods are roughly equivalent in semantics:So why would you want to do the second version instead of the first?
this
for locking which gives you more flexible locking semantics.听起来你的消息来源是错误的。在编写线程安全代码时,
syncrhonized
关键字的使用和正确使用非常重要。听起来你自己的实验证明了这一点。有关 Java 同步的更多信息:
Java 同步方法
Java 锁和同步语句
It sounds like your sources are just wrong. The
syncrhonized
keyword is important to use - and use properly - when writing thread-safe code. And it sounds like your own experiments bear this out.For more on synchronization in Java:
Java Synchronized Methods
Java Locks and Synchronized Statements
实际上,从 Java 5 开始,您(正式)在 java.util.concurrent 中拥有一组替代工具。有关更多详细信息,请参阅此处。正如本文中详细介绍的,Java 语言级别提供的监视器锁定模型具有许多重大限制,并且当存在一组复杂的相互依赖对象和锁定关系时,可能很难推理,从而使活锁成为现实。 java.util.concurrent 库提供了锁定语义,对于具有 POSIX 类系统经验的程序员来说可能会更熟悉
Actually as of Java 5 you (formally) have an alternative set of tools in java.util.concurrent. See here for more details. As detailed in the article the monitor locking model provided at Java's language level has a number of significant limitations and can be difficult to reason about when there are a complex set of interdependent objects and locking relationships making live-lock a real possibility. The java.util.concurrent library offers locking semantics which might be more familiar to programmers who've had experience in POSIX-like systems
当然,“同步”只是语法糖——非常有用的语法糖。
如果您想要无糖 Java 程序,您应该直接用 Java 字节代码编写 monitorenter、monitorexit、lock 和 解锁 VM 规范中引用的操作8.13 锁和同步
Of course, "synchronized" is just syntactic sugar - extremley useful syntactic sugar.
If you want sugar-free java programs, you should be writing directly in java byte code the monitorenter, monitorexit, lock, and unlock operations referenced in VM Specifications 8.13 Locks and Synchronization
同步是多线程环境中编程时最重要的概念之一。
在使用同步时,必须考虑发生同步的对象。
例如,如果要同步静态方法,则同步必须在类级别上使用,
如果要同步实例方法中的块,则同步必须使用在所有线程之间共享的对象的实例。
大多数人都会对第二点出错,因为它出现在代码中,其中同步似乎是在不同的对象上而不是在单个对象上。
Synchronization is one of the most important concepts while programming in multi thread environment.
While using synchronization one has to consider the object over which synchronization takes place.
For example if a static method is to be synchronized then the synchronization must be on the class level using
if the block in instance method is to be synchronized then the synchronization must be using an instance of an object which is shared between all the threads.
Most poeple go wrong with the second point as it appears in your code where the synchronization appears to be on different objects rather than a single object.