概述
在java中synchronized是一个非常重要的关键字,它主要用来控制线程同步的,在多线程环境下能实现临界区资源的互斥访问。
synchronized关键字最主要有以下3种应用方式,下面分别介绍
- 修饰实例方法,作用于当前实例加锁,进入同步代码前要获得当前实例的锁。
- 修饰静态方法,作用于当前类对象加锁,进入同步代码前要获得当前类对象的锁。
- 修饰代码块,指定加锁对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
- 修饰代码块,加锁对象为对象,则该类的所有的对象共享同一把锁。
1. 修饰实例方法
class SafeAdd implements Runnable {
public static int num = 0;
public synchronized void add() {
num ++;
}
@Override
public void run() {
for (int i = 0; i < 10000; ++i) {
add();
}
}
}
public class SyncMethod {
public static void main(String[] args) throws InterruptedException {
SafeAdd safeAdd = new SafeAdd();
Thread t1 = new Thread(safeAdd);
Thread t2 = new Thread(safeAdd);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("SafeAdd: num = " + SafeAdd.num);
}
}
运行结果:
SafeAdd: num = 20000
Process finished with exit code 0
2.修饰静态方法
class SafeAdd implements Runnable {
public static int num = 0;
public static synchronized void add() {
num ++;
}
@Override
public void run() {
for (int i = 0; i < 10000; ++i) {
add();
}
}
}
public class SyncMethod {
public static void main(String[] args) throws InterruptedException {
SafeAdd safeAdd1 = new SafeAdd();
SafeAdd safeAdd2 = new SafeAdd();
Thread t1 = new Thread(safeAdd1);
Thread t2 = new Thread(safeAdd2);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("SafeAdd: num = " + SafeAdd.num);
}
}
运行结果:
SafeAdd: num = 20000
Process finished with exit code 0
3. 同步代码块
class SafeAdd implements Runnable {
public static int num = 0;
@Override
public void run() {
synchronized (this) {
for (int i = 0; i < 10000; ++i) {
num ++;
}
}
}
}
public class SyncMethod {
public static void main(String[] args) throws InterruptedException {
SafeAdd safeAdd = new SafeAdd();
Thread t1 = new Thread(safeAdd);
Thread t2 = new Thread(safeAdd);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("SafeAdd: num = " + SafeAdd.num);
}
}
运行结果:
SafeAdd: num = 20000
Process finished with exit code 0
4. 同步代码块,加锁对象为Class对象
class SafeAdd implements Runnable {
public static int num = 0;
public static void add() {
num ++;
}
@Override
public void run() {
synchronized (SafeAdd.class) {
for (int i = 0; i < 10000; ++i) {
add();
}
}
}
}
public class SyncMethod {
public static void main(String[] args) throws InterruptedException {
SafeAdd safeAdd1 = new SafeAdd();
SafeAdd safeAdd2 = new SafeAdd();
Thread t1 = new Thread(safeAdd1);
Thread t2 = new Thread(safeAdd2);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("SafeAdd: num = " + SafeAdd.num);
}
}
运行结果:
SafeAdd: num = 20000
Process finished with exit code 0
总结
- synchronized的作用对象是实例方法和普通对象时,则多个线程仅共同争抢该对象的锁。
- synchronized的作用对象是静态方法或一个类时,则该类所有的对象共享一个锁。
来源:oschina
链接:https://my.oschina.net/u/4418236/blog/3233450