JAVA-初步认识-第十四章-线程间通信-等待唤醒机制-代码优化

一.

上一节中的代码写的并不是很眼镜,如下图中的属性,应该都是私有的。我们不应该直接访问资源中的属性,是因为它具备了不安全性。

瞎赋值怎么办呢?为了可控,意味着资源里面的属性需要被私有化,并对外提供方法访问。因此上节中的代码要进行改写。

 

首先对资源描述类进行修改,至于为什么set方法中写有两个形参,是因为name和sex同时要做赋值,因此直接将它们定义在一起。

而且类中提供了直接输出name和sex的方法,后面的程序中就不需要写那么长的输出语句了。这个输出问题比较简单

关键问题在哪儿呢?如果这么写的话,下面代码都要进行改动。为什么?无法直接调用,如r.name....这样的,只能写成r.set()。

那么真正出现多线程安全问题在哪儿呢?刚才是因为r调用了name和sex,然后在赋值时,r.name=mike, sex=nan还没赋值结束,就直接被取走了导致的。而现在,name和sex赋值在哪儿呢?在set()方法中呢,

如果这其中赋值了name,没赋sex就要出事。因此这两句话要进行同步。

我们只要保证下面三句话同步就可以了,(为什么?)这里面就可以想到,我们用什么对象都行。用自定义对象也行,用本类中的已有的this也可以。线程中的this直接写同步函数更简单。

我们知道wait和notify的方法一定要所属于这个同步,因为它本身是锁上的方法。用来操作指定线程锁上的方法。因此,我们写上了if(flag),同时这里在进行处理异常时,就不能标注r了,只能是this了。notify前面加不加this,(锁),都一样,可以省略。

说完上面的程序修改后,下面的就简单了。

真是开发中就应该是这样的,资源里封装了我的属性,同时对外提供了访问属性的方法。

如果需要同步的话,加个同步就完事了,这样不会出错。

DOS结果显示没有问题,

到目前为止,就将小示例基本搞定了,了解了如何去检验程序中出现了安全问题以后,同步的使用以及同步使用的前提,唤醒机制的使用。

 

posted @ 2017-12-17 09:00  前锋营  阅读(171)  评论(0编辑  收藏  举报