A-A+
Java-Synchronized用法(3)
Synchronized主要有以下几种用法:
1. 加在方法上:这里包括加在实例方法上、加在静态方法上。
2. 方法块:这里包括锁定this、锁定Class、锁定实例对象、锁定静态对象。
今天主要通过例子演示一下第二个用法:锁定实例对象和锁定静态对象。
首先是锁定实例对象
测试代码如下:
package com.xnck.example.sbtest;
import org.junit.Test;
import java.util.Scanner;
public class ThreadTest {
private final byte[] lockThis = new byte[0];
public void printThisLock(String input) {
synchronized (lockThis) {
System.out.println(input + System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3秒后的" + input + System.currentTimeMillis());
}
}
private void waitToQuite() {
new Scanner(System.in).next();
}
//region 测试方法
/**
* 锁定实例对象,相同对象调用等待
*/
@Test
public void test4() {
final ThreadTest test = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test.printThisLock("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test.printThisLock("我是第二个线程");
}).start();
waitToQuite();
}
/**
* 锁定实例对象,不同对象调用不需要等待
*/
@Test
public void test5() {
final ThreadTest test1 = new ThreadTest();
final ThreadTest test2 = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test1.printThisLock("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test2.printThisLock("我是第二个线程");
}).start();
waitToQuite();
}
//endregion
}
测试结果如下:

锁定实例对象,同一个对象,被调用时等待

锁定实例对象,不同对象,调用时不需要等待
然后是锁定静态对象
测试代码如下:
package com.xnck.example.sbtest;
import org.junit.Test;
import java.util.Scanner;
public class ThreadTest {
private final static byte[] lockStatic = new byte[0];
public void printStaticLock(String input) {
synchronized (lockStatic) {
System.out.println(input + System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3秒后的" + input + System.currentTimeMillis());
}
}
private void waitToQuite() {
new Scanner(System.in).next();
}
//region 测试方法
/**
* 锁定静态对象,相同对象调用等待
*/
@Test
public void test4() {
final ThreadTest test = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test.printStaticLock("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test.printStaticLock("我是第二个线程");
}).start();
waitToQuite();
}
/**
* 锁定静态对象,不同对象调用等待
*/
@Test
public void test5() {
final ThreadTest test1 = new ThreadTest();
final ThreadTest test2 = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test1.printStaticLock("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test2.printStaticLock("我是第二个线程");
}).start();
waitToQuite();
}
//endregion
}
测试结果如下:

锁定静态对象,相同对象调用需要等待

锁定静态对象,不同对象调用需要等待
