java - 线程变得困惑

标签 java multithreading

我的话题变得困惑了。 sendResult()receiveResponse() 的结果应该有不同的响应(我在 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>();

第一个线程:

    Thread.currentThread().setName(requestId);
    try
    {
        synchronized(Thread.currentThread())
        {
            switch(serviceType)
            {
                case "GCM":
                    // Send notification to android device
                    GCM gcmClass = new GCM();
                    gcmClass.authenticateRequest(deviceId, requestId, apiKey);
                    break;
            }
            // Wait for reply
            Thread.currentThread().wait();
        }
        synchronized(this)
        {
            if(confirmResult.containsKey(requestId))
            {
                // Get the result
                String result = confirmResult.get(requestId);

                // Process the result
                switch(result)
                {
                    case "approved":
                        jsonResponse.setResult(0);
                        jsonResponse.setResultText("approved");
                        break;
                    case "cancelled":
                        jsonResponse.setResult(10000);
                        jsonResponse.setResultText("cancelled");
                        break;
                }
                // Remove the key from the TreeMap
                confirmResult.remove(requestId);
            }
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }

第二个线程:

    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();
            }
        }
    }

关于java - 线程变得困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26473916/

相关文章:

java - Java 中的元数据提取?

java - 在java中哪里使用 "this"?

java - eclipse, java & 从终端运行一个项目

java - 有点混淆 SQL 和 Tomcat

c++ - 通过线程安全容器传递非线程安全对象

c# - 在一种情况下 Dispatcher.BeginInvoke 未执行

java - 如何使用HSQLDB清空表?

c++ - 在后台运行函数直到完成 MinGW + Windows

multithreading - 使用线程下载Servlet文件

multithreading - 绿色线程中的 I/O 阻塞