Java DataOutputStream不同的方法
我在一个应用程序中使用这段代码发送一些字符串并抛出一个套接字Java DataOutputStream不同的方法,java,Java,我在一个应用程序中使用这段代码发送一些字符串并抛出一个套接字 public class OutgoingData { public static DataOutputStream dos = null; public static String toSend = ""; public static volatile boolean continuousSending = true; public static String toSendTemp = ""; public static voi
public class OutgoingData {
public static DataOutputStream dos = null;
public static String toSend = "";
public static volatile boolean continuousSending = true;
public static String toSendTemp = "";
public static void startSending(final DataOutputStream d) {
new Thread(new Runnable() {
public void run() {
try {
dos = d;
while (continuousSending) {
if (!toSend.equals(toSendTemp)) {
dos.writeUTF(toSend);
dos.flush();
toSendTemp = toSend;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
我从另一个线程调用这个方法
private void send(String str) {
OutgoingData.toSend = str;
}
使用此实现是否会出现任何问题?从两个线程同步调用send()的情况除外
我不是在用这样的东西:
private void send(final String str){
new Thread(new Runnable() {
@Override
public void run() {
synchronized (OutgoingData.dos) {
try {
OutgoingData.dos.writeUTF(str);
OutgoingData.dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}).start();
}
因为运行此代码的系统对进程可以创建的线程数有限制,并且需要很长时间才能锁定对象。您的实现不是线程安全的:
if (!toSend.equals(toSendTemp)) {
// toSend can be changed before this line happens
// causing you to miss data
dos.writeUTF(toSend);
dos.flush();
// or here
toSendTemp = toSend;
}
您需要某种形式的线程同步,不管它是否“慢”。与其忙着等待字段,不如使用
阻塞队列
这将确保您永远不会错过某个值,也不会在无事可做时消耗CPU
包装队列和线程(池)的一个好方法是使用执行器服务,它同时执行这两项任务
在您的例子中,套接字流已经是一个队列,因此队列写入另一个队列很可能是多余的,您真正需要做的就是缓冲输出流
因为运行此代码的系统对进程可以创建的线程数量有限制,并且需要很长时间才能获得对象的锁
创建线程比创建线程要多100倍。理想情况下,你两个都不想要。注意:套接字已经有一个写锁。+1由于
toSend
字段不是易失性的,您可能永远不会看到此字段更改。您是对的,我没有遇到过此问题,但理论上,这很可能发生