线程多线程

时间:2013-05-17 05:48:01

标签: java multithreading synchronization

问题如下:

如下所示同时启动三个线程:

t1.start();
t2.start();
t3.start();

第一个线程(t1)的输出应该是第二个线程(t2)的输入,第二个线程(t2)的输出应该是第三个线程(t3)的输入。

你能告诉我逻辑吗?

我知道我们可以使用wait和notify方法。但我可以获得实现此输出的算法或逻辑吗?

3 个答案:

答案 0 :(得分:0)

这是一个帮助类。它在单例辅助类中实现了两个资源锁。

让每个线程使用ResourceLock.getInstance()获取实例。让线程2调用getResource1()并等待线程1完成并将其输出放在setResource1()中。这将释放锁定和线程2对getResource1()的调用返回。

重复第2和第2次线程3

在没有超时的情况下调用挂起函数并不是一个好主意。因此,超时为10秒,根据您的需要进行编辑。

package com.madinsweden.test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


public class ResourceLock {

    protected static final int TIMEOUT = 10000; //ms

    private CountDownLatch mLock1;
    private CountDownLatch mLock2;

    private Object mObject1;
    private Object mObject2;

    private static ResourceLock mInstance;

    private ResourceLock() {
        mLock1 =  new CountDownLatch(1);
        mLock2 =  new CountDownLatch(1);
    }

    public static ResourceLock getInstance() {
        if (null == mInstance) {
            mInstance = new ResourceLock();
        }
        return mInstance;
    }


    public void setObject1(Object o) {
        mObject1 = o;
        mLock1.countDown();
    }

    public Object getResource1() {
        try {
            mLock1.await(TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException("Timeout of resource lock 1");
        }
        return mObject1;
    }


    public void setObject2(Object o) {
        mObject2 = o;
        mLock2.countDown();
    }

    public Object getResource2() {
        try {
            mLock2.await(TIMEOUT, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException("Timeout of resource lock 2");
        }
        return mObject2;
    }
}

答案 1 :(得分:0)

我建议您使用ExecutorServices。这意味着更容易在线程之间传递工作。

// fields
ExecutorServices service1 = ...
ExecutorServices service2 = ...
ExecutorServices service3 = ...


// Task1 submits to service2
service1.submit(new Task1());

// service2 submits to service3

答案 2 :(得分:0)

有几种方法可以做到这一点。正如Jon指出的那样,以这种方式运行线程没有意义,因为你导致我们阻塞其他线程的输出,实际上没有实现并行化。

我的“首选”解决方案是使用ExecutorService,如彼得所提到的,虽然有点不同。这是一种天真的方法。

    ExecutorService executor = Executors.newSingleThreadExecutor();

    final Future<String> output1 = executor.submit(new Callable<String>() {
       @Override public String call() {
           // do Something
           return "a String from Task #1";

       } 
    });



    final Future<String> output2 = executor.submit(new Callable<String>() {
        @Override public String call() throws Exception{
           // do Something
           // Wait for the output of the above task using `Future.get()`.
           return output1.get() + ", a String from Task #2";

       }

    });

    Future<String> output3 = executor.submit(new Callable<String>() {
        @Override public String call() throws Exception{
           // do Something
           return output2.get() + ", a String from Task #3";

       }

    });

    System.err.print("Output from 3rd task: " + output3.get());

使用线程执行此操作的其他方法:共享阻塞数据结构(例如,线程之间的BlockingQueue以安全地发布结果。如果没有传递结果并且只需要终止其他线程的信号,则使用{ {1}} es。