同步问题:值被更改,值不同步。多个线程访问临界资源。
解决方法:
synchronized关键字
synchronized取得的锁为对象锁,且具有重入(当一个线程得到一个对象锁后,再次请求此对象锁是可以再次得到该独享锁的)功能。
当一个线程执行的代码出现异常时,其所持有的锁会自动释放。
锁不能被继承,比如你在父类的一个方法上加了synchronized,在子类中如果想要实现同步必须再次加上synchronized。
用synchronized声明方法是对当前对象加锁,synchronized代码块是对某一对象加锁。比如:
public class SynchronizedTest {
private String lock;
// 此处是对当前对象比如你使用的那个SynchronizedTest对象
synchronized public void testMethod() {
//此处是对lock对象加锁
synchronized (lock) {
System.out.println("这里是同步代码块,对lock对象加锁");
}
//此处是对当前对象加锁,和对实例方法加锁一样
synchronized (this) {
System.out.println("这里是同步代码块,对当前对象加锁");
}
}
}
调用不加synchronized关键字的方法时,不需要获取任何锁,所以不需要等待加了synchronized的代码块或者方法释放锁。所以执行顺序与那些synchronized的代码块或者方法是异步的。
调用加了synchronized(x)的代码块时,需要获取x的锁,但不需要this对象的锁,所以不需要等待synchronized(this)或者synchronized方法来释放this锁。所以前者执行顺序与后两者是异步的。前者与加了synchronized(x)的代码块是同步执行的,需要等待其执行完释放锁。
synchronized还可以加到静态方法上,即对当前对应的类进行加锁。class锁可以对类的所有对象实例起作用。
注意string常量池的问题。