使用线程执行多项操作,而无需为每个线程创建一个线程

时间:2013-07-02 05:27:46

标签: java multithreading synchronization

我有一个基本上完成相同系列步骤两次的课程。听起来像是多线程程序的完美示例。我的问题是,如果我只用两个线程就可以做到这一点。这是事物的一般要点

Tester implements Runnable{
    Thread obj1Thread, obj2Thread;
    MyObj obj1, obj2;
    String obj1Results, obj2Results;

    void runTests(){
        obj1Thread = new Thread(this, "ob1 thread");
        obj2Thread = new Thread(this, "ob2 thread");
        obj1.start();//builds up obj1
        obj2.start();//builds up obj2
        if(obj1 and obj2 are finished building){
            System.out.println(obj1);
            System.out.println(obj2);
        }
        obj1Thread.startSecondPhase()//runs a separate function that tests obj1 vs ob2. Essentially test(ob1, ob2)
        obj2Thread.startSecondPhase()//runs a separate function that tests obj2 vs ob1. Essentially test(ob2, ob1)
        if(obj1 and obj2 are finished testing){
            System.out.println(obj1Results);
            System.out.println(obj2Results);
        }     
    }
}

我得到了第一部分 - 构建对象 - 工作。我现在的问题是 -

  1. 如何让主线程等待两个线程完成第一部分?也许main会对两个对象执行wait,然后在线程notifyAll之后对主线程进行等待?但那么线程如何获得主线程?也许是this
  2. 如何在不使用新线程和新的特定运行函数创建新类的情况下运行此函数的“第二阶段”?我不想为每一项小任务创造一个新的课程和一切。
  3. 澄清我想要具体的事件顺序 -

    1. 主线程初始化并启动两个线程
    2. 两个线程同时构建各自的对象
    3. 当两个线程完成构建时,它们会暂停。然后主线程按顺序打印出对象。
    4. 主线程完成后,两个线程同时将其代码继续进入测试阶段
    5. 当线程完成后,主线程会打印出结果。可能在这里使用join()
    6. 编辑:另外,如何告诉特定线程我希望它们使用哪些对象?现在我以一种有点hacky的方式做这件事(我正在处理线程名称)。

1 个答案:

答案 0 :(得分:2)

我会使用更高级别的抽象:使用执行和ExecutorService.invokeAll(Collection<? extends Callable<T>> tasks),它返回Future的列表。

你的主线可以

  1. 发送两项任务,
  2. 获得两个期货,
  3. 打印结果,然后
  4. 再发出两项任务
  5. 执行程序服务和期货将处理引擎盖下的所有并发性。

    修改

    我看到你的评论:

      

    一个特殊的Runnable类只是为了实现一行代码?   也许我太过理想主义但对我来说感觉不对。

    在这种情况下,您通常使用无内容类:

    Future future = executorService.submit(new Runnable() {
        public void run() {
            System.out.println("Asynchronous task");
        }
    });
    

    没错。当Java有lambda时,它会变得更短。

      Future future = executorService.submit(() -> {System.out.println("Asynchronous task");});