ad_qqread_mid_big">改进synchronized
虽然在多数情况下,$task 消除了同步操作的要求,但是不是所有的多线程系统都用任务来实现。所以,还需要改进现有的线程模块。 synchronized 关键字有下列缺点: 无法指定一个超时值。 无法中断一个正在等待请求锁的线程。 无法安全地请求多个锁 。(多个锁只能以依次序获得。)
解决这些问题的办法是:扩展synchronized 的语法,使它支持多个参数和能接受一个超时说明(在下面的括弧中指定)。下面是我希望的语法:
timeoutexception是 runtimeexception 派生类,它在等待超时后即被抛出。
超时是需要的,但还不足以使代码强壮。您还需要具备从外部中止请求锁等待的能力。所以,当向一个等待锁的线程传送一个interrupt() 方法后,此方法应抛出一个 synchronizationexception 对象,并中断等待的线程。这个异常应是 runtimeexception 的一个派生类,这样不必特别处理它。
对synchronized 语法这些推荐的更改方法的主要问题是,它们需要在二进制代码级上修改。而目前这些代码使用进入监控(enter-monitor)和退出监控(exit-monitor)指令来实现 synchronized 。而这些指令没有参数,所以需要扩展二进制代码的定义以支持多个锁定请求。但是这种修改不会比在 java 2 中修改 java 虚拟机的更轻松,但它是向下兼容现存的 java 代码。
另一个可解决的问题是最常见的死锁情况,在这种情况下,两个线程都在等待对方完成某个操作。
设想一个线程调用a() ,但在获得 lock1 之后在获得 lock2 之前被剥夺运行权。 第二个线程进入运行,调用 b() ,获得了 lock2 ,但是由于第一个线程占用 lock1 ,所以它无法获得 lock1 ,所以它随后处于等待状态。此时第一个线程被唤醒,它试图获得 lock2 ,但是由于被第二个线程占据,所以无法获得。此时出现死锁。
编译器(或虚拟机)会重新排列请求锁的顺序,使lock1 总是被首先获得,这就消除了死锁。
但是,这种方法对多线程不一定总成功,所以得提供一些方法来自动打破死锁。一个简单的办法就是在等待第二个锁时常释放已获得的锁。
如果等待锁的每个程序使用不同的超时值,就可打破死锁而其中一个线程就可运行。我建议用以下的语法来取代前面的代码:
synchronized语句将永远等待,但是它时常会放弃已获得的锁以打破潜在的死锁可能。在理想情况下,每个重复等待的超时值比前一个相差一随机值。 >>>更多专题请看java线程专题
虽然在多数情况下,$task 消除了同步操作的要求,但是不是所有的多线程系统都用任务来实现。所以,还需要改进现有的线程模块。 synchronized 关键字有下列缺点: 无法指定一个超时值。 无法中断一个正在等待请求锁的线程。 无法安全地请求多个锁 。(多个锁只能以依次序获得。)
解决这些问题的办法是:扩展synchronized 的语法,使它支持多个参数和能接受一个超时说明(在下面的括弧中指定)。下面是我希望的语法:
| synchronized(x && y && z) | 获得 x、y 和 z 对象的锁。 |
| synchronized(x || y || z) | 获得 x、y 或 z 对象的锁。 |
| synchronized( (x && y ) || z) | 对于前面代码的一些扩展。 |
| synchronized(...)[1000] | 设置 1 秒超时以获得一个锁。 |
| synchronized[1000] f(){...} | 在进入 f() 函数时获得 this 的锁,但可有 1 秒超时。 |
timeoutexception是 runtimeexception 派生类,它在等待超时后即被抛出。
超时是需要的,但还不足以使代码强壮。您还需要具备从外部中止请求锁等待的能力。所以,当向一个等待锁的线程传送一个interrupt() 方法后,此方法应抛出一个 synchronizationexception 对象,并中断等待的线程。这个异常应是 runtimeexception 的一个派生类,这样不必特别处理它。
对synchronized 语法这些推荐的更改方法的主要问题是,它们需要在二进制代码级上修改。而目前这些代码使用进入监控(enter-monitor)和退出监控(exit-monitor)指令来实现 synchronized 。而这些指令没有参数,所以需要扩展二进制代码的定义以支持多个锁定请求。但是这种修改不会比在 java 2 中修改 java 虚拟机的更轻松,但它是向下兼容现存的 java 代码。
另一个可解决的问题是最常见的死锁情况,在这种情况下,两个线程都在等待对方完成某个操作。
设想一个线程调用a() ,但在获得 lock1 之后在获得 lock2 之前被剥夺运行权。 第二个线程进入运行,调用 b() ,获得了 lock2 ,但是由于第一个线程占用 lock1 ,所以它无法获得 lock1 ,所以它随后处于等待状态。此时第一个线程被唤醒,它试图获得 lock2 ,但是由于被第二个线程占据,所以无法获得。此时出现死锁。
编译器(或虚拟机)会重新排列请求锁的顺序,使lock1 总是被首先获得,这就消除了死锁。
但是,这种方法对多线程不一定总成功,所以得提供一些方法来自动打破死锁。一个简单的办法就是在等待第二个锁时常释放已获得的锁。
如果等待锁的每个程序使用不同的超时值,就可打破死锁而其中一个线程就可运行。我建议用以下的语法来取代前面的代码:
synchronized语句将永远等待,但是它时常会放弃已获得的锁以打破潜在的死锁可能。在理想情况下,每个重复等待的超时值比前一个相差一随机值。
| 上一页 1 2 3 4 下一页 |
| 相关内容:虚拟机 通信 数据库 设计 服务器 |
| 【收藏此页】【大 中 小】【打印】【关闭】 | |
| 上一篇:利用java applet编程实现动画特技 下一篇:eclipse form程序设计指南之入门 10万个软件免费高速下载 | |
| ||||||||||||||
|
|
-
关于我们
公司介绍 最新动态 联系我们 -
产品与服务
域名注册 jsp空间 php空间 -
常见问题
空间操作手册 网站备案相关 退款相关问题 -
技术支持
技术 QQ :178966803 联系电话:13616026886 联系邮箱:fjjsp@vip.163.com
扫描关注微信公众号
闽公网安备 35060202000074号