A-A+
Java-Synchronized用法(5)
Synchronized主要有以下几种用法:
1. 加在方法上:这里包括加在实例方法上、加在静态方法上。
2. 方法块:这里包括锁定this、锁定Class、锁定实例对象、锁定静态对象。
今天主要通过例子演示一下第一个用法:锁定不同的实例对象或不同的静态对象时,不同的函数方法之间的相互影响。
首先是锁定不同的实例对象时
测试代码如下:
import org.junit.Test;
import java.util.Scanner;
public class ThreadTest {
private final byte[] lockThis1 = new byte[0];
private final byte[] lockThis2 = new byte[0];
public void printThisLock1(String input) {
synchronized (lockThis1) {
System.out.println(input + System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3秒后的" + input + System.currentTimeMillis());
}
}
public void printThisLock2(String input) {
synchronized (lockThis2) {
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 test1() {
final ThreadTest test = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test.printThisLock1("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test.printThisLock2("我是第二个线程");
}).start();
waitToQuite();
}
/**
* 锁定不同的实例对象,不同对象调用不需要等待
*/
@Test
public void test2() {
final ThreadTest test1 = new ThreadTest();
final ThreadTest test2 = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test1.printThisLock1("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test2.printThisLock2("我是第二个线程");
}).start();
waitToQuite();
}
//endregion
}
测试结果如下:


其次是锁定不同的静态对象时
测试代码如下:
import org.junit.Test;
import java.util.Scanner;
public class ThreadTest {
private final static byte[] lockThis1 = new byte[0];
private final static byte[] lockThis2 = new byte[0];
public void printThisLock1(String input) {
synchronized (lockThis1) {
System.out.println(input + System.currentTimeMillis());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("3秒后的" + input + System.currentTimeMillis());
}
}
public void printThisLock2(String input) {
synchronized (lockThis2) {
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 test1() {
final ThreadTest test = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test.printThisLock1("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test.printThisLock2("我是第二个线程");
}).start();
waitToQuite();
}
/**
* 锁定不同的静态对象,不同对象调用不需要等待
*/
@Test
public void test2() {
final ThreadTest test1 = new ThreadTest();
final ThreadTest test2 = new ThreadTest();
new Thread(() -> {
System.out.println("第一个线程已启动" + System.currentTimeMillis());
test1.printThisLock1("我是第一个线程");
}).start();
new Thread(() -> {
System.out.println("第二个线程已启动" + System.currentTimeMillis());
test2.printThisLock2("我是第二个线程");
}).start();
waitToQuite();
}
//endregion
}


