1.synchronized 可以给类. 方法. 代码块加锁;而 lock 只能给代码块加锁。
2.synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。
3.通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
注:synchronized关键字在Java中用于提供线程安全的操作,它可以在以下范围内起作用:
1.同步方法:当在方法声明中使用synchronized关键字时,该方法被称为同步方法。同一时刻只能有一个线程执行该方法体,其他线程必须等待当前线程执行完毕并释放锁资源后才能访问该方法。
2.同步代码块:当在代码块上使用synchronized关键字时,同一时刻只能有一个线程执行该代码块,其他线程只有等待当前线程执行完毕并释放锁资源后才能访问该代码块。
3.同步对象:当synchronized关键字作用于一个对象时,同一时刻只能有一个线程对该对象进行访问。所有以该对象为锁的代码块都受到同步控制。
另外需要注意的是,synchronized关键字还可以用于静态方法和静态代码块。当用于静态方法时,它实际上相当于对Class实例进行同步,因为Class的相关数据存储在永久带(PermGen)中,是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁住所有调用该方法的线程。当用于静态代码块时,它与用于非静态代码块的区别在于锁定的对象不同。对于非静态代码块,锁住的是当前实例(this),而对于静态代码块,锁住的是Class实例
synchronized用法
同步方法:在方法声明上使用synchronized关键字,该方法就变成了同步方法。一次只能有一个线程执行同步方法,其他线程必须等待当前线程执行完毕并释放锁资源后才能访问该方法。例如:
java
public synchronized void synchronizedMethod() {
// …
}
同步代码块:在代码块上使用synchronized关键字,同一时刻只能有一个线程执行该代码块,其他线程只有等待当前线程执行完毕并释放锁资源后才能访问该代码块。例如:
java
public void someMethod() {
synchronized(this) {
// …
}
}
同步对象:当synchronized关键字作用于一个对象时,同一时刻只能有一个线程对该对象进行访问。所有以该对象为锁的代码块都受到同步控制。例如:
java
private Object lock = new Object();
public void someMethod() {
synchronized(lock) {
// …
}
}
在这个例子中,我们创建了一个名为lock的对象,并使用它来作为同步代码块的锁。在同一时刻,只有一个线程可以执行这个同步代码块。
需要注意的是,synchronized关键字获得的锁都是对象锁,而不是把一段代码或方法当做锁。在Java中,每个对象都有一个内置锁,如果一个方法被synchronized修饰,那么该方法所在的对象的锁就被占用,其他线程必须等待该线程释放锁后才能执行该方法。