自己的一个线程同步通讯的实例

原创 2007年09月28日 16:24:00

    在实际工作中,经常遇到在一个多步作业中由于某一步的瓶颈而制约整个作业步骤的情况,要使性能改善,我们需要发挥多线程集中

处理的作用,把较为容易的步骤先作运行产生批量数据,再交给新线程来集中处理较难的一步,这样就节省了略小于(m-1)*N的宝贵时间

。但同时,问题又出现,因为作业本是存在先后顺序的流水式,变为多个子母式并发线程,线程间的同步通信成为了需要解决的一个问题

,好在Java线程中提供了这样的一种机制,下面就通过一个实例谈谈这方面的注意事项。
在本例中,用Thread.sleep(ms)来代替具体的业务过程,整个作业分为三步:step1、step2、step3,后面将通过打印的结果讨论对性能是

否有所改善。
主调度线程:
public class Main extends Thread{
  
   public static void main(String[] args){
       PartTwo part2 = new PartTwo();
       PartOne part1 = new PartOne(part2);
       part1.start();
       part2.start();
   }
}

//---------------------------------处理简单的步骤step1、step2------------------------------------
public class PartOne extends Thread{
    private String[] docIds = new String[100];
    private PartTwo part2;
   
    public PartOne(PartTwo p2){
        this.part2 = p2;
    }
   
    public void run(){
        while (true){
            long curTime = System.currentTimeMillis();
            step1();
            step3();
            System.out.println("spend time:"+(System.currentTimeMillis()-curTime));
        }
    }
   
    public void step1(){
        long curTime = System.currentTimeMillis();
        for (int i=0; i<100; i++){
            docIds[i] = String.valueOf(i);
            try{
                sleep(100);
            }catch(InterruptedException ie){
                ie.printStackTrace();
            }
        }
        System.out.println("step1.."+(System.currentTimeMillis()-curTime));
        synchronized (part2){
            part2.notifyAll();
        }
    }
   
    public void step3(){
        long curTime = System.currentTimeMillis();
        synchronized (part2.finishSem){
            try{
                part2.finishSem.wait();
            }catch(InterruptedException ie){
                ie.printStackTrace();
            }
        }
        if (!part2.getStatus()){
            System.out.println("step2 fail...");
        }else{
            for (int i=0; i<100; i++){
                try{
                    sleep(20);
                }catch(InterruptedException ie){
                    ie.printStackTrace();
                }
            }
        }
        System.out.println("step3..."+(System.currentTimeMillis()-curTime));
    }
}

//---------------------集中式处理的线程----------------------------
public class PartTwo extends Thread{
   public Object finishSem = new Object();
   private boolean status;
  
   public PartTwo(){
   }
  
   public void run(){
       while (true){
           dosome();
       }
   }
  
   public void dosome(){
       long curTime = System.currentTimeMillis();
       try{
           synchronized (this){
               wait();
           }
           sleep(5000);  //dosomething
           System.out.println("step2...."+(System.currentTimeMillis()-curTime));
           synchronized (finishSem){
               status = true;
               finishSem.notifyAll();
           }
       }catch(InterruptedException ie){
           status = false;
           ie.printStackTrace();
       }
   }
  
   public boolean getStatus(){
       return this.status;
   }
  
}


结论:如果采用流水式作业,T(step1)=10 ms, T(step2)=4000 ms, T(step3)=20 ms, 那么100个任务所需要的时间是:T=100*

(10+4000+20)= 403,000 ms.
在比较实际运行的结果:
step1..10047
step2....15047
step3...7062
spend time:17109
节省的时间为:403000/17109≈23.55倍。
集中式处理后,三个步骤的运行时间图如下:
step1 |======>|
step2 |-------======>|
        step3 |------=======>|
Thread技术方面的总结:
wait():使当前线程陷于等待状态,并释放占用的资源,直至另外的线程将它唤醒。
notifyAll():唤醒请求而未分配到该资源的线程,通知它可以运行。
*注:这两个方法都必须在资源同步的状态下才能使用(synchronized),否则会抛出异常。
*一旦主调线程notifyAll,就意味着同时启动了一个等待该资源的线程,而不管主调线程是否已结束。
*在synchronized块中,notifyAll之前,不允许改变向量的值。 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

C#中的一个线程同步的例子

今天效率需要,需要搞定一个多线程的程序,今天我用的关键字是Monitor.Enter(this);和Monitor.Exit(this);来说一下到底锁的是什么,之前对java中的同步关键字理解的应该...

线程互斥与同步通讯

为实现线程互斥,我们一般会用到synchronized关键字来给方法,代码块进行加锁处理。 一:给方法进行加锁 直接在方法的前面的加synchronized关键字,给整个的方法上锁。public...

C#.net同步异步SOCKET通讯和多线程总结

同步套接字通信 Socket支持下的网上点对点的通信 服务端实现监听连接,客户端实现发送连接请求,建立连接后进行发送和接收数据的功能 服务器端建立一个socket,设置好本机的ip和监听的端口与...

java线程的同步互斥和通讯

一、同步和锁定 1、锁的原理 Java中每个对象都有一个内置锁。 当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例...

总结:线程同步和通讯

什么是线程同步? 当使用多个线程来访问同一个数据时,非常容易出现线程安全问题(比如多个线程都在操作同一数据导致数据不一致),所以我们用同步机制来解决这些问题。 实现同步机制有两个方法: 1...

张老师:4.传统线程同步通讯技术

问题 子线程循环10次,主线程循环100次,又子线程循环10次,主线程循环100次,如此循环50次,写出代码实现。 代码实现 /** * 将线程需要同步的资源包装在一个类里面, ...

线程的同步和通讯

先是synchronized的适用场合,对象,作用以及必要性和副作用场合:多线程并发访问资源作用:为资源(比如变量,结构,文件等)加锁副作用:同步造成延迟等待,没有多线程环境的情况下不要使用,用了这个...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)