Java同步技术(三)

版权声明

本文版权归作者所有,如有转载请与作者联系并注明出处http://blog.csdn.net/Iangao/archive/2008/10/09/3042970.aspx

 

二、高级同步技术

  信号量技术是解决线程同步问题的一条通用技术,在20世纪60到70年代人们对Dijkstra信号量做了很大的改时,信号量技术的发展达到了顶点。然而在使用信号量来解决一些复杂的同步问题时,代码的业务逻辑会显得特别复杂,因此人们又对同步技术做了很多更高层次的针某些特定问题域的抽象,对于这些特定问题域来说这些抽象使用起来会更加的直观,方便。不过需要说明的一点是,这些新的同步机制是不能解决连信号量也无法解决的问题的。

2.1 事件(Event)

2.1.1 事件简述:

   前面我们着重讨论了同步问题中关于共享资源的互斥使用的问题, 然而在同步应用中还有一类常见的应用就是几个进程(线程)之间协同应用的问题。事件(Event)是信号量操作的一种抽象, 它在信号量用于应用程序间协同方面特别有用

   下面我们给出一个queue的基本语义:对于一个事件类来说,一般有如下三个典型的方法:

  • wait(): 事件上操作会阻塞调用线程, 直到另一个线程完成对事件的signal()操作
  • signal(): 操作会正确地就绪一个被wait()事件调用所阴塞的线程,如果当signal发出时没有线程在等待,这个操作就会被忽略.
  • queue(): 操作可以返回当前等待该事件的线程数目.

2.1.2 事件的Java实现

   下面我们实现一个Event类,由于Java提供的wait,notify机制本身与Event要实现的wait和signal行为是一样的,因此Event的实现相对比校简单,我们只要在其中加入queue操作就可以了. 代码清单如下:

/**
 
* 事件
 
* @author iangao
 
*/
public
class Event {
   
private long queue=0;
   
/**
    
* 等待事件发生
    
*/
   
public synchronized void await(long mills) throws InterruptedException{
        try{
           
queue++;
            wait(mills);
        }
finally{
           
queue--;
        }

    }
   
public void await() throws InterruptedException{
        await(0);
    }
   
/**
    
* 检测等待事件的线程数量
    
*/
   
public synchronized long queue(){
       
return queue;
    }
   
/**
    
* 发送事件发生信号
    
*/
   
public synchronized void signal(){
         notifyAll();
    }
}

2.1.3 事件应用测试

   下面我们对Event事件的使用做如下测试,在本例中,我们模拟出一个救火场景,3名消防员(FireMan)监控着一栋房子(House),消防员处于警戒状态[alert.await()], 当房子火起时发起警报[alert.signal()]时,消防员会在所辖区域进行救火。当3处起火点全部收到息火消息后,房屋恢复正常使用。

/**
 
* 事件测试类
 
* @author iangao
 
*/
public class EventTest {
   
public static void main(String[] args){
       
new ThreadsTest(){
           
// 报警事件
            Event
alert=new Event();
           
// 灭火信号
            Semaphore
ok =new Semaphore();
           
/**
            
* 消防员线程
            
* @param area 管辖区域
            
*/
           
void fireMan(String area)
                        
throws InterruptedException{
               
while(true){
                    output(
"警戒...");
                   
alert.await();
                    output(
"["+area+"]:救火",random(1000,2000));
                    output(
"["+area+"]:火已灭!");
                   
ok.v();
                }
            }
           
void house() throws InterruptedException{
               
for(int i=0; i<2; i++){
                    output(
"使用中",random(3000,2000));
                    output(
"起火警报!");
                   
while(alert.queue()>0){
                       
alert.signal();
                    }
                    output(
"等待3处火全灭!");
                   
ok.p(3,0);
                    output(
"火已全灭,可以继续使用!");
                }
            }
 
          /**
           
* 启动线程: 3个消防员,一个房屋
           
*/
          
void runInThread1() throws InterruptedException{
                name(
"张三");
                fireMan(
"A");
            }
           
void runInThread2() throws InterruptedException{
                name(
"李四");
                fireMan(
"B");
            }
           
void runInThread3() throws InterruptedException{
                name(
"王五");
                fireMan(
"C");
            }
           
void runInThread4() throws InterruptedException{
                name(
"房间");
                house();
            }
        }.execute(4);
    }
}

输出结果:

[张三]: 警戒...
[李四]: 警戒...
[王五]: 警戒...
[房间]: 使用中... (4.973秒)
[房间]: 起火警报!
[张三]: [A区]:救火... (1.065秒)
[李四]: [B区]:救火... (1.562秒)
[王五]: [C区]:救火... (1.641秒)
[房间]: 等待3处火全灭!
[张三]: [A区]:火已灭!
[张三]: 警戒...
[李四]: [B区]:火已灭!
[李四]: 警戒...
[王五]: [C区]:火已灭!
[王五]: 警戒...
[房间]: 火已全灭,可以继续使用!
[房间]: 使用中... (3.313秒)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值