JAVA-初步认识-第十三章-验证静态同步函数的锁

一.

接下来更加深入地讲解一下,示例还是卖票,但是程序稍作了修改。

也就是调用的同步函数有多个修饰符,有了static的存在。

由于show函数是静态的,访问的num,那么num也要修改为静态的变量。其实num静不静态都一样,都是共享数据。

在加了两个静态修饰符后,再次编译运行一下程序。

DOS结果显示又出现了安全问题。为啥?就是验证一点,静态同步函数用的锁绝对不是this,静态方法当中根本就没有this。

这不是我们要追究的问题,问题是用的不是this,用的是啥?

同步函数有所属的对象,叫做this,使用静态就没有所属对象了。函数一进内存的时候,有对象吗?锁肯定是对象。函数进内存有对象吗?有人说函数随着类的加载而加载,函数进内存哪来的对象?到底是用哪个对象啊?是说类进内存时,静态就在了,那这个类有对象吗?按照我们当初的理解叫做,这个类还没有通过new创建对象,但是java有个特点是,字节码文件进内存是先封装对象。这个对象在哪儿讲过呢?之前我们说过,所有的对象建立它们都有自己的字节码文件对象,用getclass方法获取的。是的,就是这个对象,一进内存就有对象,这个对象就是当前class文件所属的对象。这个就是同步静态函数所使用的锁,因为只有这么一个。

该如何表示呢?有的人采用下面的格式。从编译的结果来看,已经结束了,而且没有问题。但是和我们之前说的好像有些不一样。

通过This.gerClass()拿到的确实是当前字节码文件的对象。我们来验证一下,

下图的t.getClass()获取的就是当前字节码文件对象,下图写this.getClass(),这两个获取的是同一个。肯定是嘛,为什么?就算new出多个Ticket,这个getClass都是同一个。因为同一个类才产生很多对象。t和this指向同一个对象,拿过来的是同一个对象,

很多人觉着这种方式看着变扭,可以换一种方式,之所以这么写,是因为之前咱们学过getClass。其实字节码文件表达方式还有另外形式,下图就展现了两种。

任何一个类型都有一个属性,就是小写的class。这个属性就可以直接获取该字节码文件的对象。这两种方式都可以,Ticket.class比t.getClass()强在哪儿啊?它可以直接不用创建完对象调用方法,直接用类型点class属性就可以了。这就是我们说的两种表现方式,哪一种都可以。

你要是不愿意写this.getClass(),也可以写Ticket.class,这两种形式都可以。

编译运行也没有问题。

这两种方式都行,所以咱们总结一下,

早期卖票的例子,我们用的obj对象,如果不用obj,还可以用什么?用this也行,因为对象就一个,

如果不用这个,还可以用Ticket.class。其实对象是任意的,只要保证是唯一就行,只要保证多个线程用的是同一个锁就行。

类名.class(在静态中相当于对象)在内存中必须是唯一的,根据这唯一的字节码文件创建了n多的对象。

 

posted @ 2017-12-15 11:03  前锋营  阅读(339)  评论(0编辑  收藏  举报