私は、デバイスに入力を求めて応答を受け取り、すべてをアトミック操作として受け取るメソッドを作成しようとしています。ここでなぜ同期が機能しないのですか?
は私のコードは、(query
メソッドがに焦点を当てすべきか、本当にある)である:
public class DeviceConnection implements Runnable{
//For query
static int test = 0;
//For writeline
static PrintWriter out = null; //(initialized in constructor)
//Only important for readline
static String[] systemMessage=new String[10];
static int messageIn=0;
static int messageOut=0;
static boolean connected = false;
static boolean endConnect = true;
static PrintStream logWriter; //(initialized in constructor)
static String serverName="";//(initialized in constructor)
static int socketNum;//(initialized in constructor)
/** REALLY ONLY NEED TO LOOK AT THIS METHOD
* Atomic operation to ask for data from device
* and get a response.
* @param line - query to be passed to device
* @return response from device
*/
public synchronized String query(String line){
int temp = test;
System.err.print("foo" + test);
System.err.print(this);
String response;
writeLine(line);
response = readLine();
System.err.println("bar" + test + " should be " + temp);
test = temp+1;
return response;
}
/**
* Writes a query to the device.
*<p>
* Does <b>not</b> get or handle any response
* @param line - query to be passed to device
*/
public synchronized void writeLine(String line) {
out.println(line + "\n");
}
/**
* Reads a response from device.
*<p>
* Should never be used outside of <code>query</code>
* as this could create a race condition if another
* thread is writing to the device at the same time.
* @return
*/
private synchronized String readLine() {
String response;
long start, stop;
if (messageIn != messageOut) { // new message exists
response = systemMessage[messageOut];
messageOut = (messageOut + 1) % 10;
} else {
start = System.currentTimeMillis();
try {
if (connected) { // if connected wait for heatbeats
//wait(15000);
wait();
start = System.currentTimeMillis();
} else { // if not connected ignore heartbeats
wait();
start = System.currentTimeMillis();
}
} catch (InterruptedException e) { return "Interrupted"; }
stop = System.currentTimeMillis();
if (stop - start < 12000) { // heart beats running at 5 s
if (messageIn != messageOut) { // new message exists
response = systemMessage[messageOut];
messageOut = (messageOut + 1) % 10;
} else {
return null;
}
} else { // heart beats lost
response = "Heart beats lost";
logWriter.println(response);
if (connected) { // connection lost on client side
logWriter.println("Connection to " + serverName +
" lost on client side");
sleep(60000);
connect(serverName,socketNum);
}
}
}
return response;
}
}
通常query
方法は細かい動作しますが、時々私はそうのような出力が得られます。
[email protected](other System.out stuff printed here)
[email protected] should be 59
bar60 should be 59
これはどのように可能ですか?メソッドはオブジェクト上でロックされていませんか?オブジェクトは明らかにプリントと同じですが、何とか2つのメソッドが同時に実行されています。
どのように多くのインスタンスが? –
実際にはシングルトンクラスなので、1つだけです。しかし、これは問題ではありません。出力が両方のメソッドが同じオブジェクトから呼び出されていることがはっきりと分かります(ID: 'DeviceConnection @ 7bd0bf6d') – River