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 访问服务器的单一runnable,由不同类型的请求子类划分:如何确保唯一性?_Java_Multithreading_Server_Runnable_Synchronized - Fatal编程技术网

Java 访问服务器的单一runnable,由不同类型的请求子类划分:如何确保唯一性?

Java 访问服务器的单一runnable,由不同类型的请求子类划分:如何确保唯一性?,java,multithreading,server,runnable,synchronized,Java,Multithreading,Server,Runnable,Synchronized,下面是负责与服务器通信的一个类: public abstract class AbstractCommunicationChannel implements Runnable { static String SERVER_ADDRESS = "http://0.0.0.0"; private URL url; private JSONObject requestObject; private JSONObject responseObject; Abs

下面是负责与服务器通信的一个类:

public abstract class AbstractCommunicationChannel implements Runnable {
    static String SERVER_ADDRESS = "http://0.0.0.0";

    private URL url;
    private JSONObject requestObject;
    private JSONObject responseObject;

    AbstractCommunicationChannel(URL url, JSONObject requestObject) {
        this.url = url;
        this.requestObject = requestObject;
    }

    /**
     * This is the general purpose tool for hitting the server and getting a response back.
     */
    public void run() {
        Log.i("requestObject", requestObject.toString());
        try {
            HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setRequestMethod("POST");
            httpUrlConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8");

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpUrlConnection.getOutputStream());
            outputStreamWriter.write(requestObject.toString());
            outputStreamWriter.flush();
            outputStreamWriter.close();
            /* * */
            InputStream inputStream = httpUrlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int result = bufferedInputStream.read();
            while (result != -1) {
                byteArrayOutputStream.write((byte) result);
                result = bufferedInputStream.read();
            }
            responseObject = new JSONObject(byteArrayOutputStream.toString("UTF-8"));
            httpUrlConnection.disconnect();
        } catch (Exception ignored) {
        }
        processResponse(responseObject);
    }

    protected abstract void processResponse(JSONObject responseObject);
}
下面是一个示例子类,负责特定类型的请求:

public class LoginRequester extends AbstractCommunicationChannel {

    public LoginRequester(String username, String password) throws Exception {
        super(new URL(SERVER_ADDRESS + ":0000/login"),
            new JSONObject().put("username", username).put("password", password));
    }

    @Override
    protected void processResponse(JSONObject responseObject) {
        try {
            if (responseObject.get("result").equals("valid")) {
                StartActivity.accessAccountActivity();
            }

            if (responseObject.get("result").equals("username")) {
                Toast.makeText(StartActivity.startContext, "No such username exists!", Toast.LENGTH_LONG).show();
            }
            if (responseObject.get("result").equals("password")) {
                Toast.makeText(StartActivity.startContext, "Invalid password!", Toast.LENGTH_LONG).show();
            }
        } catch (Exception ignored) {
        }
    }
}
就上下文而言,这里是另一个:

public class CreateRequester extends AbstractCommunicationChannel {

    public CreateRequester(String username, String password) throws Exception {
        super(new URL(SERVER_ADDRESS + ":8080/create"),
            new JSONObject().put("username", username).put("password", password));
    }

    @Override
    protected void processResponse(JSONObject responseObject) {
        try {
            if (responseObject.get("result").equals("success")) {
                StartActivity.accessAccountActivity();

            } else {

                Toast.makeText(StartActivity.startContext, "ERROR!", Toast.LENGTH_LONG).show();
            }
        } catch (Exception ignored) {
        }
    }
}

我想要的是,只有一个实体能够向服务器发出请求,那么是否有某种方法可以使
AbstractCommunicationChannel
同步,以确保在任何时候都不能有两个或更多线程与服务器通信

您可以在抽象类中使用类级锁(如果您使用单类加载器):

类级锁防止多个线程在运行时进入类的任何可用实例中的同步块。

例如:

public abstract class AbstractCommunicationChannel implements Runnable {
   private static Object lock = new Object();

    public void run() {
      synchronized(lock){
        Log.i("requestObject", requestObject.toString());
        try {
            HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setRequestMethod("POST");
            httpUrlConnection.setRequestProperty("Content-Type", "application/json; charset=utf-8");

            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(httpUrlConnection.getOutputStream());
            outputStreamWriter.write(requestObject.toString());
            outputStreamWriter.flush();
            outputStreamWriter.close();
            /* * */
            InputStream inputStream = httpUrlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            int result = bufferedInputStream.read();
            while (result != -1) {
                byteArrayOutputStream.write((byte) result);
                result = bufferedInputStream.read();
            }
            responseObject = new JSONObject(byteArrayOutputStream.toString("UTF-8"));
            httpUrlConnection.disconnect();
        } catch (Exception ignored) {
        }
     }
        processResponse(responseObject);
    }

我必须在调用这些可运行项的类中传递这个
对象吗?我最近也在想,如果每个类中都有一个专用线程来访问这个功能,当我们进入这个类时,我们在这个线程上执行runnable,当我们离开这个类时,我们杀死这个线程-你怎么看?锁在AbstractClass中应该是私有的,通过这种方式,AbstractClass有责任使用这个锁,并且您不会强制sbuclaccess实现锁周围的逻辑。你可以按照你的建议去做,但是你必须处理有点复杂的线程。使用我建议的模式,您可以这样做:CreateRequester请求=新建CreateRequest(…);CompletableFuture.runAsync(请求);请求将在另一个线程中执行,依此类推。。这比只实现一个能够运行请求的线程更容易。我真的不明白你的意思,我相信随着我的深入思考,它会更有意义,但是,伙计,我想知道,你是否有兴趣一起做一个谷歌聚会,通过架构讨论线程模型?也许是星期天什么的