我遇到了一个奇怪的问题,它没有出现在MACOS上,只有linux ...... 当我在linux中运行以下代码时,我有时会得到一条不一致的消息。 代码只创建两个线程,其中一个发送大量的字节数组,所有的1到另一个,另一个线程只检查所有内容是否为1。它偶尔发生(似乎它取决于n ..)它收到0。
有人能帮助我吗?
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestIO {
static final int n = 500000;
final static byte d = 10;
static class SenderRunnable implements Runnable {
SenderRunnable () {}
private ServerSocket sock;
protected OutputStream os;
public void run() {
try {
sock = new ServerSocket(12345); // create socket and bind to port
Socket clientSock = sock.accept(); // wait for client to connect
os = clientSock.getOutputStream();
byte[] a = new byte[10];
for(int i = 0; i < 10; ++i)
a[i] = d;
for (int i = 0; i < n; i++) {
os.write(a);
}
os.flush();
sock.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
static class ReceiverRunnable implements Runnable {
ReceiverRunnable () {}
private Socket sock;
public InputStream is;
public void run() {
try {
sock = new java.net.Socket("localhost", 12345); // create socket and connect
is = sock.getInputStream();
for (int i = 0; i < n; i++) {
byte[] temp = new byte[10];
is.read(temp);
for(int j = 0; j < 10; ++j)
if(temp[j] != d){
System.out.println("weird!"+" "+i+" "+j+" "+temp[j]);
}
}
sock.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
public static void test1Case() throws Exception {
SenderRunnable sender = new SenderRunnable();
ReceiverRunnable receiver = new ReceiverRunnable();
Thread tSnd = new Thread(sender);
Thread tRcv = new Thread(receiver);
tSnd.start();
tRcv.start();
tSnd.join();
tRcv.join();
}
public static void main(String[] args)throws Exception {
test1Case();
test1Case();
test1Case();
test1Case();
test1Case();
test1Case();
test1Case();
test1Case();
}
}
谢谢!我将部分代码更改为以下内容,现在可以正常工作。
for (int i = 0; i < n; i++) {
byte[] temp = new byte[10];
int remain = 10;
remain -= is.read(temp);
while(0 != remain)
{
remain -= is.read(temp, 10-remain, remain);
}
for(int j = 0; j < 10; ++j)
if(temp[j] != d){
System.out.println("weird!"+" "+i+" "+j+" "+temp[j]);
}
}
答案 0 :(得分:0)
你的错误在于读者方面。
方法read()
无法保证填充您的数组。它只接收已经可用的字节并返回已经获得的字节数。所以你必须在循环中读取字节,直到read返回-1。
答案 1 :(得分:0)
您应该在调用InputStream.read()
http://docs.oracle.com/javase/7/docs/api/java/io/InputStream.html#read(byte[])