我可以在 RESTful 网络服务中使用 wait() 吗?
Can I use wait() in a RESTful webservice?
我有一个 RESTful 网络服务,用于 NetBeans 上的服务器。
此 Web 服务应该从客户端(多人游戏)收到很多请求。
我对这个话题还很陌生,但如果我理解正确的话——客户端对我的网络服务的每次调用都是线程安全的——因为每个与网络服务的连接都在不同的线程上(我所有的变量都在里面网络服务方法)这是真的吗?
这让我想到了我的问题:
我可以在网络服务方法中使用 wait();
吗?假设我正在等待两个客户端连接,所以第二个连接将使用 notifyAll();
但是由于 webservice 并不是真正的线程,我不知道是否可以在那里使用这些方法?我应该改用什么??
这是我的网络服务:
@Path("/w")
public class JSONRESTService {
String returned;
@POST
@Consumes("application/json")
@Path("/JSONService")
public String JSONREST(InputStream incomingData) {
StringBuilder JSONBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incomingData));
String line = null;
while ((line = in.readLine()) != null) {
JSONBuilder.append(line);
}
returned = "transfer was completed";
// This is what I'm trying to add but I know that I can't:
// count is a static variable, every new connection will increase this value
// only one player is connected
if (Utility.count == 1)
wait (); //wait for a 2nd player to connect to this webservice
// 2nd player is connected to this webservice
if (Utility.count == 2)
notifyAll (); // notify the 1st player
} catch (Exception e) {
System.out.println ("Error Parsing: - ");
returned ="error";
}
System.out.println ("Data Received: " + JSONBuilder.toString ());
return (returned);
}
}
客户:
JSONObject jsonObject = new JSONObject("string");
// Step2: Now pass JSON File Data to REST Service
try {
URL url = new URL("http://localhost:8080/w/JSONService");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(jsonObject.toString());
out.close();
//string answer from server:
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer sb = new StringBuffer("");
String line="";
while ((line = in.readLine()) != null) {
sb.append(line);
System.out.println("\n"+line);
in.close();
} catch (Exception e) {
System.out.println("\nError while calling JSON REST Service");
System.out.println(e);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
} } }`
是的。方法内部的所有局部变量都是thread-safe。 Class 字段变量可能是 thread-safe 也可能不是。它是由你决定。如果 rest controller 具有单例范围(通常默认情况下它具有),则意味着 class 字段在所有请求之间共享。
因此,从技术上讲,您可以使用一些共享锁对象对其进行同步。尝试去做。但最好在异步模式下进行。请参阅 this 文章中使用长轮询的反向 Ajax Comet 技术。
或者您可以使用 Reverse Ajax with Websockets 并在没有任何空闲的情况下将 'Transfer was received' 发送回客户端。
您始终可以使用 wait()
和 notify()
,因为它会影响代码所在的线程 运行。要不要用要看情况。
如果你想要玩家队列,那么使用队列:)
我举的一个小例子...
@Path("/w")
public class JSONRESTService {
private static BlockingQueue<Player> queue = new ArrayBlockingQueue<>(999);
@POST
@Consumes("application/json")
@Path("/JSONService")
public String JSONREST(InputStream incomingData) {
Player thisPlayer = ...; // Get player from session or something
System.out.println (thisPlayer.getName() + " starting...");
try {
if (queue.isEmpty()) {
System.out.println ("waiting for an opponent");
queue.add(thisPlayer);
synchronized (thisPlayer) {
thisPlayer.wait();
}
} else {
System.out.println ("get next in queue");
Player opponent = queue.take();
opponent.setOpponent(thisPlayer);
thisPlayer.setOpponent(opponent);
synchronized (opponent) {
opponent.notify();
}
}
System.out.println (thisPlayer.getName() + " playing " + thisPlayer.getOpponent().getName());
} catch (Exception ex) {
ex.printStackTrace();
}
}
static class Player {
private String name;
private Player opponent;
Player (String name) {
this.name = name;
}
public String getName() {
return name;
}
public Player getOpponent() {
return opponent;
}
public void setOpponent(Player opponent) {
this.opponent = opponent;
}
}
}
我有一个 RESTful 网络服务,用于 NetBeans 上的服务器。 此 Web 服务应该从客户端(多人游戏)收到很多请求。
我对这个话题还很陌生,但如果我理解正确的话——客户端对我的网络服务的每次调用都是线程安全的——因为每个与网络服务的连接都在不同的线程上(我所有的变量都在里面网络服务方法)这是真的吗?
这让我想到了我的问题:
我可以在网络服务方法中使用 wait();
吗?假设我正在等待两个客户端连接,所以第二个连接将使用 notifyAll();
但是由于 webservice 并不是真正的线程,我不知道是否可以在那里使用这些方法?我应该改用什么??
这是我的网络服务:
@Path("/w")
public class JSONRESTService {
String returned;
@POST
@Consumes("application/json")
@Path("/JSONService")
public String JSONREST(InputStream incomingData) {
StringBuilder JSONBuilder = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new InputStreamReader(incomingData));
String line = null;
while ((line = in.readLine()) != null) {
JSONBuilder.append(line);
}
returned = "transfer was completed";
// This is what I'm trying to add but I know that I can't:
// count is a static variable, every new connection will increase this value
// only one player is connected
if (Utility.count == 1)
wait (); //wait for a 2nd player to connect to this webservice
// 2nd player is connected to this webservice
if (Utility.count == 2)
notifyAll (); // notify the 1st player
} catch (Exception e) {
System.out.println ("Error Parsing: - ");
returned ="error";
}
System.out.println ("Data Received: " + JSONBuilder.toString ());
return (returned);
}
}
客户:
JSONObject jsonObject = new JSONObject("string");
// Step2: Now pass JSON File Data to REST Service
try {
URL url = new URL("http://localhost:8080/w/JSONService");
URLConnection connection = url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json");
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream());
out.write(jsonObject.toString());
out.close();
//string answer from server:
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer sb = new StringBuffer("");
String line="";
while ((line = in.readLine()) != null) {
sb.append(line);
System.out.println("\n"+line);
in.close();
} catch (Exception e) {
System.out.println("\nError while calling JSON REST Service");
System.out.println(e);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
} } }`
是的。方法内部的所有局部变量都是thread-safe。 Class 字段变量可能是 thread-safe 也可能不是。它是由你决定。如果 rest controller 具有单例范围(通常默认情况下它具有),则意味着 class 字段在所有请求之间共享。
因此,从技术上讲,您可以使用一些共享锁对象对其进行同步。尝试去做。但最好在异步模式下进行。请参阅 this 文章中使用长轮询的反向 Ajax Comet 技术。
或者您可以使用 Reverse Ajax with Websockets 并在没有任何空闲的情况下将 'Transfer was received' 发送回客户端。
您始终可以使用 wait()
和 notify()
,因为它会影响代码所在的线程 运行。要不要用要看情况。
如果你想要玩家队列,那么使用队列:)
我举的一个小例子...
@Path("/w")
public class JSONRESTService {
private static BlockingQueue<Player> queue = new ArrayBlockingQueue<>(999);
@POST
@Consumes("application/json")
@Path("/JSONService")
public String JSONREST(InputStream incomingData) {
Player thisPlayer = ...; // Get player from session or something
System.out.println (thisPlayer.getName() + " starting...");
try {
if (queue.isEmpty()) {
System.out.println ("waiting for an opponent");
queue.add(thisPlayer);
synchronized (thisPlayer) {
thisPlayer.wait();
}
} else {
System.out.println ("get next in queue");
Player opponent = queue.take();
opponent.setOpponent(thisPlayer);
thisPlayer.setOpponent(opponent);
synchronized (opponent) {
opponent.notify();
}
}
System.out.println (thisPlayer.getName() + " playing " + thisPlayer.getOpponent().getName());
} catch (Exception ex) {
ex.printStackTrace();
}
}
static class Player {
private String name;
private Player opponent;
Player (String name) {
this.name = name;
}
public String getName() {
return name;
}
public Player getOpponent() {
return opponent;
}
public void setOpponent(Player opponent) {
this.opponent = opponent;
}
}
}