java多线程开发--语法糖之synchronized关键字
介绍
相信接触过java多线程开发的朋友对于synchronized关键词并不陌生。在java中一切皆对象理念,每个对象都包含一个monitor,用处之一就是在多线程操作时加锁(lock)解锁(unlock)。
synchronized关键字在声明之后会定义一个代码执行段block{},synchronized可以包含参数——synchronized(Object A)
1. 当对象A为null时,执行synchronized会抛出NullPointerException;
2. 当对象A不为null时,synchronized会尝试锁住(lock)对象A的monitor;
a)如果lock成功,那么会执行定义的代码执行段block{},直到退出代码执行段block{}时调用解锁(unlock)对象A的monitor;
b)如果lock失败,那么说明此时有其他线程占用对象A的monitor,当前线程会继续等待直到对象A的monitor空闲lock成功才继续步骤a)的操作;
当前知道的synchronized有三种使用方式:
1. 显示指明对象 sychronized(a);
此时synchronized被调用时会使用对象a的monitor;
2. 在类的方法定义中声明 public synchronized void setter();
此时synchronized被调用时会使用当前对象this的monitor;
3. 在类的静态方法定义中声明 public synchronized void setter();
此时synchronized被调用时会使用当前类的class的monitor;
例子
上面文绉绉的概念解释完了,接下来让我们用代码来演示吧;
public class SynchronizedKeyword {
private int number = 0;
public static void main(String args[]) {
SynchronizedKeyword demo = new SynchronizedKeyword();
demo.testUnsynchronized();
demo.number = 0;
demo.testSynchronizedObectMethod();
demo.number = 0;
demo.testSynchronizedStaticMethod();
}
private void processNumber() {
for (int i = 0; i < 3; i++) {
System.out.println(Thread.currentThread().getName() + " number: " + number);
number++;
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized void processNumber2() {
processNumber();
}
private static synchronized void processNumber3(SynchronizedKeyword target) {
target.processNumber();
}
private void testUnsynchronized() {
System.out.println("testUnsynchronized: 本方法主要测试多线程同步没有synchronized关键字时打印number时的两个线程同时打印.");
System.out.println("testUnsynchronized-->begin");
Thread t1 = new Thread() {
@Override
public void run() {
processNumber();
}
};
Thread t2 = new Thread() {
@Override
public void run() {
processNumber();
}
};
t1.setName("unsynchronizedTest_t1");
t1.start();
t2.setName("unsynchronizedTest_t2");
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testUnsynchronized-->end");
}
private void testSynchronizedObectMethod() {
System.out.println("testSynchronizedObjectMethod: 本方法主要测试多线程同步:非静态方法通过synchronized关键字实现多线程先后顺序打印number.");
System.out.println("testSynchronizedObjectMethod-->begin");
Thread t1 = new Thread() {
@Override
public void run() {
processNumber2();
}
};
Thread t2 = new Thread() {
@Override
public void run() {
synchronized (SynchronizedKeyword.this) {
processNumber();
}
}
};
t1.setName("testSynchronizedObjectMethod_t1");
t1.start();
t2.setName("testSynchronizedObjectMethod_t2");
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testSynchronizedObjectMethod-->end");
}
private void testSynchronizedStaticMethod() {
System.out.println("testSynchronizedStaticMethod: 本方法主要测试多线程同步:静态方法通过synchronized关键字实现多线程先后顺序打印number.");
System.out.println("testSynchronizedStaticMethod-->begin");
Thread t1 = new Thread() {
@Override
public void run() {
processNumber3(SynchronizedKeyword.this);
}
};
Thread t2 = new Thread() {
@Override
public void run() {
synchronized (SynchronizedKeyword.class) {
processNumber();
}
}
};
t1.setName("testSynchronizedStaticMethod_t1");
t1.start();
t2.setName("testSynchronizedStaticMethod_t2");
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("testSynchronizedStaticMethod-->end");
}
}
输出结果
testUnsynchronized: 本方法主要测试多线程同步没有synchronized关键字时打印number时的两个线程同时打印.
testUnsynchronized-->begin
unsynchronizedTest_t1 number: 0
unsynchronizedTest_t2 number: 1
unsynchronizedTest_t2 number: 2
unsynchronizedTest_t1 number: 3
unsynchronizedTest_t1 number: 4
unsynchronizedTest_t2 number: 5
testUnsynchronized-->end
testSynchronizedObjectMethod: 本方法主要测试多线程同步:非静态方法通过synchronized关键字实现多线程先后顺序打印number.
testSynchronizedObjectMethod-->begin
testSynchronizedObjectMethod_t1 number: 0
testSynchronizedObjectMethod_t1 number: 1
testSynchronizedObjectMethod_t1 number: 2
testSynchronizedObjectMethod_t2 number: 3
testSynchronizedObjectMethod_t2 number: 4
testSynchronizedObjectMethod_t2 number: 5
testSynchronizedObjectMethod-->end
testSynchronizedStaticMethod: 本方法主要测试多线程同步:静态方法通过synchronized关键字实现多线程先后顺序打印number.
testSynchronizedStaticMethod-->begin
testSynchronizedStaticMethod_t1 number: 0
testSynchronizedStaticMethod_t1 number: 1
testSynchronizedStaticMethod_t1 number: 2
testSynchronizedStaticMethod_t2 number: 3
testSynchronizedStaticMethod_t2 number: 4
testSynchronizedStaticMethod_t2 number: 5
testSynchronizedStaticMethod-->end
Process finished with exit code 0