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(请求);请求将在另一个线程中执行,依此类推。。这比只实现一个能够运行请求的线程更容易。我真的不明白你的意思,我相信随着我的深入思考,它会更有意义,但是,伙计,我想知道,你是否有兴趣一起做一个谷歌聚会,通过架构讨论线程模型?也许是星期天什么的