两条线程的互斥合作就是指,当一条线程在工作时另一条线程挂起。
问题的提出:
我想做一个动太显示随机个数的Label。
实现:
1)一开始用一条线程搞个随机数循环控制,不过,完成 repaint()速度远远小于控制数据的更新速度,所以实在运行时label得不到显示。
2)于是用两条线程来做,这样是可以的。
另一个问题又来了:怎样实现这两条线程的强烈互斥合作?必需要等到一条控制数据的线程把数据修改完成了,另一条控制刷新的
线程去刷新才有用啊。
一开始用的设计模式是:
thread1{ while(true){ do1(); synchronized(1){ 1.notify(); } synchronized(2){ 2.wait(); } } } | tread2{ while(true){ do2(); synchronized(2){
2.notify(); } synchronized(1){ 1.wait(); } } } |
但这从理论上以是不可以的了。会造成死锁。
于是改为这样:
thread1{ while(true){ do1(); change(1); } synchronized change(flag){ if(flag==1){ synchronized(1){ 1.notify(); } synchronized(2){ 2.wait(); } }else{ synchronized(2){ 2.notify(); } synchronized(1){ 1.wait(); } } | thread2{ while(true){ do2(); thread2.change(2); } } |
这个设计想通过原子操作来实现notify与wait同时完成而不会出现因为时间片完成的问题而只运行完notify时cpu不得不运行另一条线程。
这样也会造成死锁,想想看,change()是独占的,只要一条线程进去了,执行了一个wait,这个资源就会给一个挂起的线程占有,这样的话别的线程也不能用,只能等待。于是死锁产生了。
最后只能取消notify与wait模式,改为用计数器。
thread1{ int flag=0; run(){
while(true){ handel(1); } } synchronized handel(int own){ if(flag==0&&own==0){ do1(); }else if(flag==1&&own==0){ do2(); } flag=(flag+1)%2; } | thread2{ run(){ while(true){ handel(2); } }
|
这样就可以实现了两条线程的合作,缺点就是:这是CPU主动询问模式,而不是触发模式,会耗cpu时间。
完整代码如下 :
大家如果有更好的方法,希望一起讨论。