Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 线程多线程_Java_Multithreading_Synchronization - Fatal编程技术网

Java 线程多线程

Java 线程多线程,java,multithreading,synchronization,Java,Multithreading,Synchronization,问题如下: t1.start(); t2.start(); t3.start(); 三个线程同时启动,如下所示: t1.start(); t2.start(); t3.start(); 第一个线程(t1)的输出应该是第二个线程(t2)的输入,第二个线程(t2)的输出应该是第三个线程(t3)的输入 你能告诉我逻辑吗 我知道我们可以使用对象的wait和notify方法。但是我可以得到实现此输出的算法或逻辑吗?这里有一个帮助器类供您使用。它在一个单例助手类中实现了两个资源锁 让每个线程使用Reso

问题如下:

t1.start();
t2.start();
t3.start();
三个线程同时启动,如下所示:

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

你能告诉我逻辑吗


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

这里有一个帮助器类供您使用。它在一个单例助手类中实现了两个资源锁

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

对螺纹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;
    }
}

我建议你使用这些服务。这意味着更容易在线程之间传递工作

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


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

// service2 submits to service3

有几种方法可以做到这一点。正如Jon所指出的,以这种方式运行线程没有任何意义,因为您正在导致它们被其他线程的输出阻塞,实际上无法实现并行化

我的“首选”解决方案是使用
ExecutorService
,正如Peter提到的,尽管有点不同。这里有一个天真的方法

    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());
ExecutorService executor=Executors.newSingleThreadExecutor();
最终未来输出1=executor.submit(新的可调用(){
@重写公共字符串调用(){
//做点什么
返回“任务#1中的字符串”;
} 
});
最终未来输出2=executor.submit(新的可调用(){
@重写公共字符串调用()引发异常{
//做点什么
//使用“Future.get()”等待上述任务的输出。
返回output1.get()+“,一个来自任务#2”的字符串;
}
});
Future output3=executor.submit(新的可调用(){
@重写公共字符串调用()引发异常{
//做点什么
返回output2.get()+”,一个来自任务#3”的字符串;
}
});
System.err.print(“第三个任务的输出:+output3.get());


使用线程执行此操作的其他方法:共享块数据结构(例如,
BlockingQueue
在线程之间安全地发布结果。如果没有结果传递,只需要向其他线程发出终止信号,您可以使用
CountDownLatch
es。

每个线程是否有一个输出?如果是这样,您根本不应该使用单独的线程……第二个线程将无法执行此操作。)任何有用的东西,直到第一个线程完成,等等。你说的o/p和i/p是什么意思?输出/输入?如果它们相互依赖,为什么要使用线程?o/p指的是输出,i/p指的是输出input@Nicholas:我相信是的-我对问题进行了编辑,使其更易于阅读。种族条件、键入“不安全”和“独生子女”?而不是甚至提到这种情况一开始可能不应该存在…?No hire.cHao请详细说明竞争条件。例如,
getInstance()
(两个线程同时调用它可能会创建两个
ResourceLock
s,任何发布到其中一个的内容在另一个线程上都不可见。)这应该是同步的。其次,你不必要地通过使用超时将CPU时间与挂钟时间混为一谈。如果一项任务合法地占用了10秒以上,你仍然认为它失败了。是的,你可以增加超时时间,但在较慢的机器上仍然会遇到问题。没有令人信服的理由不让thread2像我一样等待第三,如果发布了多个项目(这是这样的设置有意义的唯一情况),如果thread1在thread2检索到第一个项目之前发布第二个项目,第一个项目就会消失。