synchronized 锁定的到底是什么


java 的锁,常用是synchronized,(当然还有Lock,后续如果有时间,会补充到后面),那么synchronized锁定的到底是什么呢?对象还是锁的是方法。

这里我暂时只说非static的例子,static的例子,后续会补充。


我们一般使用synchronized,以下两种

1)

synchronized void test(){}


2)

void test(){

synchronized (?){

}}


在实际应用中,还是需要了解synchronized 到底是什么的,这有助于我们处理对业务需求。为了解决synchronized 到底是什么,请看一下代码?

我写一个锁定方法的例子:

public class Main {

public synchronized void test(int k){
try {
System.out.println("Thread "+k +"  satrt");
Thread.sleep(10000);
System.out.println("Thread "+k +"  end");
} catch (InterruptedException e) {
}
}

}


在写一个线程类

class Test1 extends Thread{

private int num=0;

public Test1(int num) {
this.num = num;
}


@Override
public void run() {
new Main().test(num);
}

}


我在Main 类加主main方法:

public class Main {



public static void main(String[] args) {
new Test1(1).start();
new Test1(2).start();
new Test1(3).start();
}

}


执行结果:

Thread 1  satrt
Thread 3  satrt
Thread 2  satrt
Thread 2  end
Thread 3  end
Thread 1  end


可见synchronized 没有生效,都执行了。没有按照我们的想法去做。


下面我对 synchronized 方法进行下修改:

public void test(int k){
synchronized(this){
try {
System.out.println("Thread "+k +"  satrt");
Thread.sleep(10000);
System.out.println("Thread "+k +"  end");
} catch (InterruptedException e) {
}
}
}

在执行结果:

Thread 1  satrt
Thread 2  satrt
Thread 3  satrt
Thread 1  end
Thread 3  end
Thread 2  end

没有任何改变,和我们期望的不一致。


我们对上面的类进行一下修改:

public class Main {
public static void main(String[] args) {
Main main = new Main();

new Test1(1,main).start();
new Test1(2,main).start();
new Test1(3,main).start();
}

public synchronized void test(int k){
try {
System.out.println("Thread "+k +"  satrt");
Thread.sleep(10000);
System.out.println("Thread "+k +"  end");
} catch (InterruptedException e) {
}
}
}


对线程类也做一点修改:

class Test1 extends Thread{

private int num=0;
private Main main;

public Test1(int num,Main main) {
this.num = num;
this.main =main;
}


@Override
public void run() {
main.test(num);
}

}

执行下得到结果:

Thread 1  satrt
Thread 1  end
Thread 3  satrt
Thread 3  end
Thread 2  satrt
Thread 2  end

这是我们期望看到的结果。


由此得出结论: 对非static的synchronized 方法或者对象,都是只锁定该对象中的该方法,而不是锁定方法本身。


如果我们期望全局锁定方法,我们继续对上面的方法进行修改。

主类:

public class Main {



public static void main(String[] args) {
new Test1(1).start();
new Test1(2).start();
new Test1(3).start();
}

public static synchronized void test(int k){
try {
System.out.println("Thread "+k +"  satrt");
Thread.sleep(10000);
System.out.println("Thread "+k +"  end");
} catch (InterruptedException e) {
}
}
}


线程类:

class Test1 extends Thread{

private int num=0;

public Test1(int num) {
this.num = num;
}


@Override
public void run() {
test(num);
}

}


结果是:

Thread 1  satrt
Thread 1  end
Thread 3  satrt
Thread 3  end
Thread 2  satrt
Thread 2  end

这是我们期望的结果。


在做另外一种修改:

public class Main {



public static void main(String[] args) {
new Test1(1).start();
new Test1(2).start();
new Test1(3).start();
}

public void test(int k){
synchronized(Main.class){
try {
System.out.println("Thread "+k +"  satrt");
Thread.sleep(10000);
System.out.println("Thread "+k +"  end");
} catch (InterruptedException e) {
}
}
}
}


class Test1 extends Thread{

private int num=0;

public Test1(int num) {
this.num = num;
}


@Override
public void run() {
new Main().test(num);
}

}


结果是:

Thread 1  satrt
Thread 1  end
Thread 2  satrt
Thread 2  end
Thread 3  satrt
Thread 3  end


有由此我得出结论:我们期望全局锁定表,可以选择将方法变成static的synchronized这个类的class。


总结以上所得:

总结:
    sync(this) 锁定的是具体对象实例中的代码块。
    sync 函数 锁定的是具体对象实例中的函数代码块。
    sync(*.class) 锁定的是所有对象的实例,也就是所有该类构建的对象的全局锁。
    static sync 函数锁定的是所有对象实例的该函数代码块。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值