在多线程并发编程中,synchronized一直是元老级角色,很多人称呼它为重量级锁。随着Java SE1.6对synchronized的优化,在一些情况下它已经没那么重了。
synchronized应用
synchronized主要有三种应用方式:作用于实例方法、作用于静态方法以及作用于代码块。
1. 作用于实例方法:
public class SynchronizedDemo implements Runnable{
static int x = 0;
private synchronized void increase(){
for (int i = 0 ; i < 100000 ; i++){
x++;
}
}
@Override
public void run() {
increase();
}
public static void main(String[] args) throws InterruptedException {
SynchronizedDemo synchronizedInstance = new SynchronizedDemo();
//线程访问同一个对象的实例方法
Thread t1 = new Thread(synchronizedInstance);
Thread t2 = new Thread(synchronizedInstance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
输出结果:2000000
public class SynchronizedDemo implements Runnable{
static int x = 0;
private synchronized void increase(){
for (int i = 0 ; i < 1000000 ; i++){
x++;
}
}
@Override
public void run() {
increase();
}
public static void main(String[] args) throws InterruptedException {
//线程访问不同对象的实例方法
Thread t1 = new Thread(new SynchronizedDemo());
Thread t2 = new Thread(new SynchronizedDemo());
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
输出结果:1526077
结论: synchronized作用于普通实例方法时,锁的是同一个实例对象。
2. 作用于静态方法:
public class SynchronizedDemo implements Runnable{
static int x = 0;
//synchronized作用于静态方法
private static synchronized void increase(){
for (int i = 0 ; i < 1000000 ; i++){
x++;
}
}
@Override
public void run() {
increase();
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new SynchronizedDemo());
Thread t2 = new Thread(new SynchronizedDemo());
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
输出结果:2000000
结论: synchronized作用于静态方法时,锁的是当前类的class对象。
3. 作用于代码块:
public class SynchronizedDemo implements Runnable{
static Thread t1 = new Thread(new SynchronizedDemo());
static Thread t2 = new Thread(new SynchronizedDemo());
static int x = 0;
private synchronized void increase(){
//锁的是当前实例对象
synchronized (this) {
for (int i = 0 ; i < 1000000 ; i++){
x++;
}
}
}
@Override
public void run() {
increase();
}
public static void main(String[] args) throws InterruptedException {
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
输出结果: 999854
public class SynchronizedDemo implements Runnable{
static Thread t1 = new Thread(new SynchronizedDemo());
static Thread t2 = new Thread(new SynchronizedDemo());
static int x = 0;
private synchronized void increase(){
//锁的是当前类的class对象
synchronized (SynchronizedDemo.class) {
for (int i = 0 ; i < 1000000 ; i++){
x++;
}
}
}
@Override
public void run() {
increase();
}
public static void main(String[] args) throws InterruptedException {
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(x);
}
}
输出结果: 2000000
结论: synchronized作用于代码块时,可选择锁住当前实例对象(this) 和 锁住当前类的class对象(类.class)
synchronized优化
jdk1.6