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

原创 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之前,不允许改变向量的值。 

java中有几种方法可以实现一个线程?用什么关键字修饰同步方法 stop()和suspend()方法为何不推荐使用?

java5以前,有两种实现方法,分别使用new Thread()和new Thread(runnable)形式,第一种继承Thread类,直接调用thread的run方法,所以,我们往往使用Threa...
  • Amen_Wu
  • Amen_Wu
  • 2017年01月04日 23:22
  • 1277

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

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

Java知识点整理:第十四章:java多线程编程、创建一个线程、异步与同步、java反射、类加载

以下均为简单的知识点,并没有涉及代码和较深的解析,见谅,后续会针对知识点进行展开,深入进行剖析。 1.java多线程编程     java语言的优势之一就是线程处理较为简单     一般操作系统都支...

java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?

java5以前,有如下两种: 第一种: new Thread(){}.start();这表示调用Thread子类对象的run方法,new Thread(){}表示一个Thread的匿名子类的实例对...

java中 如何终止一个线程

  • 2012年02月24日 13:12
  • 35KB
  • 下载

C#.net同步异步SOCKET通讯和多线程总结(5)tcp发送和接受的代码

基于TCP协议的发送和接收端 TCP协议的接收端 using System.Net.Sockets ; //使用到TcpListen类 using System.Threading ; //使用...
  • lgheden
  • lgheden
  • 2013年07月16日 10:20
  • 1766

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

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

线程通讯和同步的两种实现方法

在多线程编程中,不免要涉及同步和通讯两个方面。同步有两种方法实现,一种是利用synchronized标示,另外一种是加锁。生成锁的对象的方法是:privatestatic Lock lock = ne...

线程互斥与同步通讯

为实现线程互斥,我们一般会用到synchronized关键字来给方法,代码块进行加锁处理。 一:给方法进行加锁 直接在方法的前面的加synchronized关键字,给整个的方法上锁。public...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:自己的一个线程同步通讯的实例
举报原因:
原因补充:

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