打字猴:1.700450229e+09
1700450229
1700450230 系统正常运行:2
1700450231
1700450232 线程Thread-1出现异常,自行重启,请分析原因。
1700450233
1700450234 java.lang.RuntimeException
1700450235
1700450236 at TcpServer.run(Client.java:30)
1700450237
1700450238 at java.lang.Thread.run(Thread.java:619)
1700450239
1700450240 从运行结果上也可以看出,当Thread-0出现异常时,系统自动启动了Thread-1线程,继续提供服务,大大提高了系统的可靠性。
1700450241
1700450242 这段程序只是一个示例程序,若要在实际环境中应用,则需要注意以下三个方面:
1700450243
1700450244 (1)共享资源锁定
1700450245
1700450246 如果线程异常产生的原因是资源被锁定,自动重启应用只会增加系统的负担,无法提供不间断服务。例如一个即时通信服务器(XMPP Server)出现信息不能写入的情况时,即使再怎么重启服务,也是无法解决问题的。在此情况下最好的办法是停止所有的线程,释放资源。
1700450247
1700450248 (2)脏数据引起系统逻辑混乱
1700450249
1700450250 异常的产生中断了正在执行的业务逻辑,特别是如果正在执行一个原子操作(像即时通信服务器的用户验证和签到这两个事件应该在一个操作中处理,不允许出现验证成功但签到不成功的情况),但如果此时抛出了运行期异常就有可能会破坏正常的业务逻辑,例如出现用户认证通过了,但签到不成功的情况,在这种情景下重启应用服务器,虽然可以提供服务,但对部分用户则产生了逻辑异常。
1700450251
1700450252 (3)内存溢出
1700450253
1700450254 线程异常了,但由该线程创建的对象并不会马上回收,如果再重新启动新线程,再创建一批新对象,特别是加入了场景接管,就非常危险了,例如即时通信服务,重新启动一个新线程必须保证原在线用户的透明性,即用户不会察觉服务重启,在此种情况下,就需要在线程初始化时加载大量对象以保证用户的状态信息,但是如果线程反复重启,很可能会引起OutOfMemory内存泄露问题。
1700450255
1700450256
1700450257
1700450258
1700450259 编写高质量代码:改善Java程序的151个建议 [:1700438198]
1700450260 编写高质量代码:改善Java程序的151个建议 建议123:volatile不能保证数据同步
1700450261
1700450262 volatile关键字比较少用,原因无外乎两点,一是在Java 1.5之前该关键字在不同的操作系统上有不同的表现,所带来的问题就是移植性较差;二是比较难设计,而且误用较多,这也导致它的“名誉”受损。
1700450263
1700450264 我们知道,每个线程都运行在栈内存中,每个线程都有自己的工作内存(Working Memory,比如寄存器Register、高速缓冲存储器Cache等),线程的计算一般是通过工作内存进行交互的,其示意图如图9-1所示。
1700450265
1700450266
1700450267
1700450268
1700450269 图9-1 线程读取变量的示意图
1700450270
1700450271 从示意图上我们可以看到,线程在初始化时从主内存中加载所需的变量值到工作内存中,然后在线程运行时,如果是读取,则直接从工作内存中读取,若是写入则先写到工作内存中,之后再刷新到主存中,这是JVM的一个简单的内存模型,但是这样的结构在多线程的情况下有可能会出现问题,比如:A线程修改变量的值,也刷新到了主存中,但B、C线程在此时间内读取的还是本线程的工作内存,也就是说它们读取的不是最“新鲜”的值,此时就出现了不同线程持有的公共资源不同步的情况。
1700450272
1700450273 对于此类问题有很多解决办法,比如使用synchronized同步代码块,或者使用Lock锁来解决该问题,不过,Java可以使用volatile更简单地解决此类问题,比如在一个变量前加上volatile关键字,可以确保每个线程对本地变量的访问和修改都是直接与主内存交互的,而不是与本线程的工作内存交互的,保证每个线程都能获得最“新鲜”的变量值,其示意图如图9-2所示。
1700450274
1700450275
1700450276
1700450277
1700450278 图9-2 volatile变量操作示意图
[ 上一页 ]  [ :1.700450229e+09 ]  [ 下一页 ]