Java关键字 可以用来修饰通常用来修饰方法,代码块。也可以修饰类。能够确保在同一时刻最多只有一个线程运行该代码,防止并发操作!
- 当两个并发线程访问统一个对象object中的这个synchronized(this)同步代码时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块之后才能得以执行该代码块。
- 不过,当一个线程访问object的一个synchronized(this){}同步代码块时,其他线程对object中所有非synchronized(this)同步代码块。
- 重点,当一个线程访问object的synchronized(this){}同步代码块时,其他线程对object中其他synchronized(this){}同步代码块的访问也会被阻塞。
- 以上三个例子,对同步代码块,对象锁,同样适用。放一个线程访问object的一个synchronized(this)同步代码时,它就获得这个object的对象锁,结果,其他线程对该object对象所有的同步操作都会被阻塞。
同步关键是看是否使用的是不是同一把锁。
比如:
synchronized修饰普通方法,同步锁即为这个方法被调用的对象。如果是同一个对象执行两个同步方法,就可以是实现同步。如果我们创建了两个对象,那个这两个同步方法也不同实现同步。
synchronized修饰静态方法,同步锁即为这个方法被调用的类。如果使用对象调用,因为不是同一把锁,所以并不能实现同步,必须使用Class.fun()才可以实现同步。
synchronized同步缺陷
因为synchronized同步代码锁定了对象锁,阻塞了其他线程对该代码块的调用。如果此代码块比较大,那将大大影响效率。典型的,若将线程类的run()方法声明为synchronized,由于在线程的整个声明周期内他一直在运行,因此将导致对本类任何synchronized的方法永远都得不到调用。
解决办法:使用synchronized代码块,语法如下:
synchronized{
//允许访问控制的代码
}
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (可以是类实例或类)的锁方能执行,具体机
制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活性较高。