验证同步函数(静态与非静态)的锁是否是Object

来源:互联网 发布:魔兽副本数据库 编辑:程序博客网 时间:2024/04/30 15:17

一、首先验证非静态同步函数锁
两条线程分别运行两个方法,测试同步函数show()是否与run()函数一样,使用的都是Object作为锁。

class Ticket implements Runnable{    private int num = 200;    Object obj = new Object();    boolean flag = true;    @Override    public void run() {        if(flag){            while(true){                synchronized (obj) {                    if(num > 0){                        try {Thread.sleep(10);} catch (Exception e) {} //模拟处理时间                        System.out.println("run..."+Thread.currentThread().getName()+"...."+num--);                    }                }            }        }else{            while(true)            show();        }    }    public synchronized void show(){        if(num > 0){            try {Thread.sleep(10);} catch (Exception e) {}//模拟处理时间            System.out.println("show..."+Thread.currentThread().getName()+"..."+num--);        }    }}public class Test {    public static void main(String[] args) {        Ticket t = new Ticket();        Thread t1 = new Thread(t);        Thread t2 = new Thread(t);        t1.start();        try {Thread.sleep(10);} catch (Exception e) {} //减慢速度,不然因为电脑速度过快导致测试不出结果        t.flag = false;        t2.start();    }}

测试结果

run...Thread-0....1show...Thread-1...1

打印的信息中,出现了重复的num,故同步函数的锁并非Object
查资料知,非静态同步函数锁为this,将synchronized (obj)改为synchronized (this)即可验证。

二、验证静态同步函数锁
public synchronized void show()改为public static synchronized void show()
synchronized (obj)改为synchronized (this.getClass())或者synchronized (Ticket.class)
可知

    通过验证发现 同步函数如果被静态修饰后,不再以this 为锁     静态进内存时,内存中没有本类对象,但是一定有该类的字节码文件对象     类名.class  该对象的类型是class     静态的同步方法,使用的锁是该方法所在类的字节码文件对象。类名.class 

原因——静态变量优先于对象存在

所谓的静态变量优先于对象存在,是说当你的类被加载到内存中时,被static修饰的变量也会随着类的加载而加载到内存中,而这个类的对象此时并没有出现,只有当你申明并实例化这个类的变量时,才会在内存中开辟空间存放该类的对象,所以当类加载后,可以直接调用类名.变量名直接调用,因为其在内存中已经存在,而对象暂时还没有。
0 0
原创粉丝点击