测试代码
/**
*@ClassName Test
*@Description TODO
*@Author luziyuan
*@Date 2020-03-22 15:04
*@Version 1.0
**/
public class Test {
public void test() {
synchronized (this) {
System.out.println("test开始..");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("test结束..");
}
}
}
class MyThread extends Thread {
public void run() {
Test sync = new Test();
sync.test();
}
}
class Main {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
Thread thread = new MyThread();
thread.start();
}
}
}
以上代码输出的结果是
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
奇怪,为什么?我们不是在方法前加了synchronized吗?为什么还是会出现多个线程同时进来这个方法?
解答:首先解释一下,在方法前面加synchronized,其实就是拿当前对象的锁,也相当于synchronized (this),也就是说走到这个方法中后,这个方法持有这个Sync对象的锁,但是可以看到我们每次走到run方法中,都会新建一个Sync对象,所以才导致了这个问题,想一想,每次new一个Sync对象,每次都拿一个新的Sync对象的锁,所以可以多线程同时运行synchronized方法或代码段。
这个问题。。。。。。直到想明白之后才发现,其实还是自己基础不太好。
将以上代码修改为如下就可以了,我们只创建一个对象,让所有线程都拿一个Sync对象作为锁
/**
*@ClassName Test
*@Description TODO
*@Author luziyuan
*@Date 2020-03-22 15:04
*@Version 1.0
**/
public class Test {
public void test() {
synchronized (this) {
System.out.println("test开始..");
System.out.println("test结束..");
}
}
}
class MyThread implements Runnable {
private Test test;
public MyThread(Test test){
this.test=test;
}
public void run() {
test.test();
}
}
class Main {
public static void main(String[] args) {
Test sync = new Test();
for (int i = 0; i < 3; i++) {
Thread thread = new Thread(new MyThread(sync));
thread.start();
}
}
}
输出结果
test开始..
test结束..
test开始..
test结束..
test开始..
test结束..
或者还有一种方案直接将上面的这个方法中的代码锁了, synchronized (Test.Class); 这样也可以成功锁住
如果解决了你的问题
点个赞吧