'同步'真的只是语法糖吗?

Cam*_*Cam 6 java multithreading synchronized

我是多线程的新手,我编写了这段代码,它通过同时运行线程递增并打印变量来打印数字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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这工作 - 我写了一个测试程序来检查输出,打印的数字按顺序正好是1-10000.

我的问题是:我听说这synchronized只是语法糖.但是,如果不使用它,我似乎无法取得成功.我错过了什么?

JUS*_*ION 14

synchronized什么都不是语法糖.如果不使用synchronized关键字,就无法在Java中使用锁.

在Java中锁定中存在一种"语法糖"的地方synchronized可以应用于块(如上所述)和整个方法.以下两种方法在语义上大致相同:

synchronized void method1() {
  // ... do stuff ...
}

void method2() {
  synchronized(this) {
    // ... do stuff ...
  }
}
Run Code Online (Sandbox Code Playgroud)

那你为什么要做第二个版本而不是第一个呢?

  • 同步方法调用比普通的旧方法调用慢得多,比如大约一个数量级.如果您的同步代码不能保证始终执行(比如说它是在条件中),那么您可能不希望同步整个方法.
  • 同步方法保持锁定比同步块更长(因为所有方法设置/拆除代码).上面的第二种方法将锁定时间更短,因为设置和拆除堆栈帧所花费的时间不会被锁定.
  • 如果使用同步块,您可以更精确地控制您正在锁定的内容.
  • (由starblue提供)同步块可以使用除this锁定之外的对象,这为您提供了更灵活的锁定语义.

  • 从java 1.5开始,你可以通过java.util.concurrent.Lock来保护对关键区域的访问.这实际上比在1.5和1.6中使用synchronized更快.所以你的开场陈述是错误的. (4认同)
  • 你有前两个要点的参考吗? (2认同)