我在一个应用程序中使用这个代码来发送一些字符串,抛出一个套接字。
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();
}因为运行此代码的系统对进程可以创建的线程数有限制,并且需要很长时间才能锁定对象。
发布于 2013-10-22 23:40:52
您的实现不是线程安全的:
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;
}你需要某种形式的线程同步,不管它是否“慢”。
发布于 2013-10-23 00:02:01
与忙于等待字段相比,更好的选择是使用BlockingQueue<String>,这将确保您不会遗漏任何值,也不会在无事可做时消耗CPU。
包装一个队列和一个线程(池)的一个好方法是使用一个同时完成这两个任务的ExecutorService。
在您的示例中,套接字流已经是一个队列,因此排队写入另一个队列可能是多余的,并且您真正需要的就是缓冲您的输出流。
,因为运行此代码的系统对进程可以创建的线程数有限制,并且需要很长时间才能锁定对象。
创建线程的工作量是创建线程的100倍以上。理想情况下,你不会想要其中任何一个。注意:套接字已经有一个写锁。
https://stackoverflow.com/questions/19522095
复制相似问题