Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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 - Fatal编程技术网

Java 线程混淆

Java 线程混淆,java,multithreading,Java,Multithreading,我的思路搞混了。sendResult()和receiverResponse()的结果都应该有不同的响应(我在servlet中用JSON响应)。 但是,它们都以sendResult()的响应进行回复 有人能解释为什么会这样,以及如何解决这个问题吗 class Authenticate { String t2RequestId = null; String finalUserInput = null; public synchronized String sendAuthe

我的思路搞混了。
sendResult()
receiverResponse()
的结果都应该有不同的响应(我在servlet中用JSON响应)。 但是,它们都以
sendResult()
的响应进行回复

有人能解释为什么会这样,以及如何解决这个问题吗

class Authenticate {
    String t2RequestId = null;
    String finalUserInput = null;

    public synchronized String sendAuthentication(String deviceId, String requestId, String apiKey) {
        // Send notification
        GCM gcmClass = new GCM();
        gcmClass.authenticateRequest(deviceId, requestId, apiKey);

        while(!t2RequestId.equals(requestId)) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return finalUserInput;
    }

    public synchronized void receiveAuthentication(String userInput, String requestId) {
        finalUserInput = userInput;
        t2RequestId = requestId;
        notifyAll();
    }
}

class T1 implements Runnable {
    Authenticate m;
    private final String deviceId;
    private final String requestId;
    private final String apiKey;
    String result;
    public T1(Authenticate m1, String deviceId, String requestId, String apiKey) {
        this.m = m1;
        this.deviceId = deviceId;
        this.requestId = requestId;
        this.apiKey = apiKey;
        Thread t1 = new Thread(this, requestId);
        t1.start();

        // Wait for thread to finish before sending response
        try {
            t1.join();
        } catch(InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void run() {
       result = m.sendAuthentication(deviceId, requestId, apiKey);
    }
    public String getResult() {
        return result;
    }
}

class T2 implements Runnable {
    Authenticate m;
    private final String requestId;
    private final String userInput;
    public T2(Authenticate m2, String requestId, String userInput) {
        this.m = m2;
        this.requestId = requestId;
        this.userInput = userInput;
        Thread t2 = new Thread(this, "t2" + requestId);
        t2.start();
    }

    public void run() {
        m.receiveAuthentication(userInput, requestId);
    }
}
public class AuthenticationHandler {
    final static Authenticate m = new Authenticate();

    public static String sendRequest(String deviceId, String requestId, String apiKey) {
        T1 runnable = new T1(m, deviceId, requestId, apiKey);
        String result = runnable.getResult();
        return result;
    }
    public static void receiveResponse(String requestId, String userInput) {
        new T2(m, requestId, userInput);
    }
}
我发现了一种更好的(?)方式来处理线程通信,我认为,对于感兴趣的人来说:

全局变量:

TreeMap<String, String> confirmResult = new TreeMap<String, String>();
第二个线程:

    synchronized(this)
    {
        // Put the result in the TreeMap
        confirmResult.put(requestId, confirmation);
    }
    // Get a list of all threads
    Map<Thread, StackTraceElement[]> arr = Thread.getAllStackTraces();
    // List the threads
    for(Map.Entry<Thread, StackTraceElement[]> entry : arr.entrySet())
    {
        // Check if the notify thread still exists
        if(entry.getKey().getName().equals(requestId))
        {
            synchronized(entry.getKey())
            {
                // Notify the thread
                entry.getKey().notify();
            }
        }
    }
已同步(此)
{
//将结果放入树形图中
confirmResult.put(请求ID,确认);
}
//获取所有线程的列表
Map arr=Thread.getAllStackTraces();
//列出线程
对于(Map.Entry:arr.entrySet())
{
//检查通知线程是否仍然存在
if(entry.getKey().getName().equals(requestId))
{
已同步(entry.getKey())
{
//通知线程
entry.getKey().notify();
}
}
}

有些情况我不明白。T1初始化,主线程等待T1线程。但T1线程等待响应,所以T2无法运行。您在哪里调用sendRequest和ReceiverResponse?您确定从servlet得到响应吗?另外,notify不是一个好的解决方案,因为它随机通知线程。例如,您有30个线程在等待,您调用了notify,然后您随机选择了一个线程,这样您的类的状态可能会成为一个大问题。@user3087839 sendRequest和ReceiverResponse在servlet接收到JSON请求时都会被调用。我从servlet得到了一个响应,只有两个请求得到了相同的响应,这是不应该发生的。有没有一种方法可以叫一个特定的线程,也许是名字?我在编程方面还不是很在行,已经尝试了大约一个月了,所以我不知道“类保持状态”是什么意思。。。你能详细解释一下吗?我不太明白你在问什么。这里的代码太多了,您可能会删除一半,但仍然可以演示您感兴趣的行为。另外,
Runnable
对象不应该创建自己的线程。您应该直接调用
run
,或者将其传递给线程或执行器。在构造函数中这样做尤其不合适。
    synchronized(this)
    {
        // Put the result in the TreeMap
        confirmResult.put(requestId, confirmation);
    }
    // Get a list of all threads
    Map<Thread, StackTraceElement[]> arr = Thread.getAllStackTraces();
    // List the threads
    for(Map.Entry<Thread, StackTraceElement[]> entry : arr.entrySet())
    {
        // Check if the notify thread still exists
        if(entry.getKey().getName().equals(requestId))
        {
            synchronized(entry.getKey())
            {
                // Notify the thread
                entry.getKey().notify();
            }
        }
    }