Stuck in Interation which is protected by a semaphore - java

For learning purposes, I am implementing UDP with the mechanisms of TCP (so that it guarantees safe transfer).
The Semaphore I am using is binary, so its sem = new Semaphore(1);.
I use this semaphore to control the entrance for my sendBuf, which is a List containing all packages which have been send, but not yet confirmed. Since I sometimes remove packages out of it when I get an ACK, I need to make sure I am not iterating with one thread while another thread is deleting something out of it.
The thing which is really bugging me is this:
public void timeoutTask(long seqNum) {
System.out.println("Timeout for package with SeqNum " + seqNum
+ " happened.");
timeoutValue *= 2;
try {
System.out.println("Acquire? in timeouttask");
sem.acquire();
System.out.println("Acquired! in timeouttask");
} catch (InterruptedException e1) {
System.out.println("semaphore not acquired");
e1.printStackTrace();
}for (FCpacket packet : sendBuf) {
System.out.println("Iterating!");
if (packet.getSeqNum() == seqNum) {
System.out.println("Package for seqNum " + seqNum + " found!");
reSendData = packet.getSeqNumBytesAndData();
DatagramPacket reSendPacket = new DatagramPacket(reSendData,
reSendData.length, hostaddress, SERVER_PORT);
try {
clientSocket.send(reSendPacket);
System.out.println("Packet with seq " + seqNum
+ " send again");
packet.setTimestamp(0);
startTimer(packet);
new ReceiveHandler(reSendData, reSendData.length,
clientSocket, rcvData, UDP_PACKET_SIZE, this).run();
} catch (IOException e) {
System.out.println("Couldn't send package");
e.printStackTrace();
}
}
}
sem.release();
System.out.println("released! in timeouttask");
Console output gives me the following:
Acquire? in timeouttask
Acquired! in timeouttask
Iterating!
Paket for seqNum 1 found!
Packet with seq 1 send again
So it gets the semaphore, starts iterating, it even sends the package, so by now it should Either: Iterate again ("iterating!") OR release the semaphore. None of the above happens, it is just stuck. I have no idea why - any ideas?

If ReceiveHandler is a Thread, it should be invoked as
new ReceiveHandler(reSendData, reSendData.length, clientSocket, rcvData, UDP_PACKET_SIZE, this).start();
But if it is a Runnable, it should be invoked as
new Thread(new ReceiveHandler(reSendData, reSendData.length, clientSocket, rcvData, UDP_PACKET_SIZE, this)).start();
run() will not execute the task in a separate Thread.
see: What's the difference between Thread start() and Runnable run()

Related

Java take() Method of LinkedBlockingQueue is stuck, even if the Queue should not be empty

I'm writing Code for a Network Application. Therefor I'm using a LinkedBlockingQueue to store incoming messaged until they are consumed. The following code runs in it's own Thread and fills up the Queue:
while(true) {
String msg = in.readLine();
if(msg == null) continue;
recieveQueue.offer(msg);
System.out.println("recieveQueue.offer() called at: " + System.currentTimeMillis() + " hash:" + recieveQueue.hashCode());
System.out.println("Server recieved: " + msg.replace("\n", ""));
break;
}
Next I wrote a Method, which runs in the same "Main-Thread" (No extra Thread is created for this Method). It's only called when the stored Elements have to be consumed. It looks like the following:
public String recieveMessage() {
try {
System.out.println("recieveQueue.take() called at: " + System.currentTimeMillis() + " hash:" + recieveQueue.hashCode());
return recieveQueue.take();
}catch(InterruptedException e) {
e.printStackTrace();
return null;
}
}
When running this Code I get the following output:
recieveQueue.offer() called at: 1594558123030 hash:2091496189
Server recieved: CONFIRMED
recieveQueue.take() called at: 1594558123031 hash:2091496189
The hash verifies that I'm working on the same Queue, and as seen by the Time, recieveQueue.offer(msg) is definitely called before take() and so the Queue should contain a message. But the Program stops at the take() call. No Exceptions were thrown and there is no other point in the code where take() gets called. I waited for like 10 minutes but the take() call never finishes
Made few changes in your program.
Note: Please check in your code Consumer in while loop.
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class Main
{
public static void main(String[] args) {
BlockingQueue recieveQueue = new LinkedBlockingQueue<String>(10);
new Thread(){
public void run(){
int count=0;
while(true) {
count++;
String msg = "AAA:"+count;
if(msg == null) continue;
recieveQueue.offer(msg);
System.out.println("recieveQueue.offer() called at: " + System.currentTimeMillis() + " hash:" + recieveQueue.hashCode());
System.out.println("Server recieved: " + msg.replace("\n", ""));
}
}
}.start();
while(true){
try {
System.out.println("recieveQueue.take() called at: " + System.currentTimeMillis() + " hash:" + recieveQueue.hashCode());
System.out.println("recieveQueue.take() : "+recieveQueue.take());
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
}

Socket server stream messages in stream are mixed

I am implementing multiplayer game with server socket mechanism.
Game is running in one loop mechanism.
Server only broadcast any message to every player connected.
Server creates thread for every connected player
Messages are JSONs and they are being sent every 100ms from client side.
Messages are being broadcasted by server and read by client without any interval.
This is server loop:
while (true) {
try {
System.out.println("LISTENING...");
Socket clientSocket = serverSocket.accept();
System.out.println("GOT CONNECTION");
PlayerThread playerThread = new PlayerThread(clientSocket);
playerThread.start();
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Exception occured on server");
break;
}
}
This is PlayerThread loop:
while (true) {
try {
String inputMessage = in.readUTF();
System.out.println("GOT: " + inputMessage);
JsonNode jsonNode = objectMapper.readTree(inputMessage);
String senderName = jsonNode.get("senderName").asText();
if (!players.contains(this)) {
playerName = senderName;
players.add(this);
}
for (PlayerThread p : players) {
p.getOut().writeUTF(inputMessage);
}
And finally listening to messages:
public void listen() {
if (connected) {
try {
if (in.available() > 0) {
String inputMessage = in.readUTF();
System.out.println("GOT MESSAGE: " + inputMessage);
handleMessages(inputMessage);
}
} catch (IOException e) {
LOGGER.log(Level.INFO, "Connection lost");
connected = false;
}
} else
LOGGER.log(Level.INFO, "Player is not connected");
}
Method above is run in main game loop. It checks if there's something in inputStream and then reads it.
This is how correct message looks like:
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 52","posX":10.0,"posY":5.0}
It works ok when there are 2 players, but the more players connect the more probably is to get message like this (or similiar broken messages):
GOT MESSAGE: 0} U{"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 65","posX":10.0,"posY":5.0}
or
GOT MESSAGE: {"type":"UPDATE_STATE","content":null,"senderName":"GRACZ 24","pos
There different errors in message like Y letter, half-message or multiple messages in one row. Why such thing happen? It looks like when there are more players and they write into output stream in server side, this stream is not read yet so they are appending and appending. But it doesn't explain why there are broken and most imporant, how to resolve it?
I can move reading stream to another thread because in.readUTF() locks process but I wanted to keep it synchronized in main game loop and I don't think this will help (am I wrong?)
You need to synchronize your write loop on an object that's common between all PlayerThreads so that messages don't interleave.
synchronized(/*Should be a "global" server object*/) {
for (PlayerThread p : players) {
p.getOut().writeUTF(inputMessage);
}
}

Condition Check fails in run() of a Thread

public class MultiThreadExample extends Thread {
public static int count=0;
static String s="";
synchronized public static String read(){
String line="";
System.out.println("Enter new line:");
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
try {
line=br.readLine();
count++;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return line;
}
synchronized public static void write(String line){
try {
BufferedWriter br=new BufferedWriter(new FileWriter("C://name.txt"));
br.write(line);
System.out.println(line);
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run(){
if(count==0){
System.out.println("Read " + s + " Count " + count);
s=read();
System.out.println("Read " + s + " Count " + count);
}
else{
write(s);
System.out.println("Write" + s + " Count " + count);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MultiThreadExample th1=new MultiThreadExample();
MultiThreadExample th2=new MultiThreadExample();
th1.start();
th2.start();
}
}
The count check in run() method is not working. Any idea why? The count increases with each call, I can see, but the check is not working, and each time the control passes to read() method, and does not go to write()
What am I doing wrong? Also, is there any other efficient way to call multiple methods from a two threads, depending on situation?
P.S. I am trying to read input using one thread, and write the input value to a file in another thread
try this:
MultiThreadExample th1=new MultiThreadExample();
MultiThreadExample th2=new MultiThreadExample();
th1.start();
try {
th1.join();
} catch (InterruptedException ex) {
System.out.println(ex.getMessage());
}
th2.start();
Don't create a new BufferedReader for every line. Use the same one for the life of the socket. You're losing data read-ahead by each BufferedReader.
Remove all the static except main method ... All you need to ensure is that read and write don't change/read "count" at the same time ... Use a different lock object like "lockObject" and use wait() and notify(). You are looking for a producer/consumer sort of a pattern here. Here is an example: http://www.programcreek.com/2009/02/notify-and-wait-example/
can also try 'similar' approach. , which ever thread enters first reads, and the later one waits for the former to read and then it writes. (it doesn't need your static methods to be synchronized)
static ReentrantLock l = new ReentrantLock();
public void run(){
l.lock();
if(count==0){
System.out.println("Read " + s + " Count " + count);
s=read();
l.unlock();
System.out.println("Read " + s + " Count " + count);
}
else{
write(s);
System.out.println("Write" + s + " Count " + count);
}
}
Okay, can you please explain to me, why my previous code was not working, and the check failed?
#Shail016 explained it in a comment on your question. Here's one possible sequence of events.
main thread calls th1.start(), calls th2.start(), and then exits.
thread 1 enters the run() method, sees that count==0, enters the read() method, calls System.out.println(...)
thread 2 enters the run() method, sees that count==0, tries to enter the read() method, gets blocked, waiting for the mutex.
thread 1 returns from the System.out.println(...) call, reads a line, increments count, and returns,
thread 2 is allowed in to read(), etc., etc.,
etc.
etc.
Mark count as volatile. This ensures that changes from one thread are seen by other threads. As long as only one thread updates count, this is OK, otherwise, you could use either an AtomicInteger, an AtomicIntegerFieldUpdater in conjunction with a volatile field or (if you measure high contention, which is unlikely in your case) a LongAdder (all classes are from the java.util.concurrent.atomic package, the last is only available in Java 8).

Only works in debugging mode

I'm trying to create a program for a distributed system. At the moment I have a thread for listening to connections, and a thread for sending, and a thread for receiving.
I've reached a problem where the client will connect but only when using breakpoints. I can't figure out the problem at all!. I've tried to implement things to slow the program down however nothing is working.
If you guys could take a look i'd be greatly appreciative.
public static void main(String[] args)
{
System.out.println("Server starting on port 5000");
RecievingConnection reciever = new RecievingConnection(5000,0); //Recieving Connection
reciever.start();
SendingConnection sender = new SendingConnection(5001,1); //Sending Connection
sender.start();
while(true){
while(reciever.ready==true){
System.out.println("In");
nodes first = new nodes(reciever.socket,0);
System.out.println("Node created");
first.start();
System.out.println("Client connected on port: " + reciever.socket.getLocalAddress());
nodes second = new nodes(sender.socket,1);
second.start();
reciever.ready=false;
sender.ready=false;
reciever.connectionComplete=true;
sender.connectionComplete=true;
}
}
}
public RecievingConnection(int port, int mode)
{
Serverport = port;
connectionMode = mode;
try{
server = new ServerSocket(port);
server.setSoTimeout(100000);
}
catch(IOException ex)
{
System.out.println(ex);
}
}
public void run(){
while(true){
if(ready == false){
try {
socket = server.accept();
ready = true;
System.out.println("Attempting to connect using port: " + Serverport);
while(connectionComplete == false){
//wait
}
} catch (IOException ex) {
System.out.println(ex);
}
}
}
}
The sending thread is basically the same code. Any idea what the problem is? "Nodes" is the thread for each node.
I solved it by adding a sleep in the main thread. I presume this is because the main thread takes priority over child threads?
Your problem is almost certainly at:
while (connectionComplete == false) {
//wait
}
This will loop forever, the other thtreads will not get any cpu time at all. It also explains why it works in debug - it's because in debug if you stop at a breakpoint, any other threads will get time.
You should at least do:
while (connectionComplete == false) {
//wait
Thread.sleep(0);
}
and maybe use a number much greater than 0. This will allow other thtreads a chance to run.
I am not suggesting that this will make your code work correctly but it should remove the current problem.
After that there's another tight loop that won't let any other thread time.
while (true) {
if (ready == false) {
Change that to:
while (true) {
if (ready == false) {
// ...
} else {
// Here too.
Thread.sleep(0);
}
}
You can't just share variables between threads. Make them volatile, synchronize or use CAS types like AtomicBoolean.
Read about it.
https://docs.oracle.com/javase/tutorial/essential/concurrency/interfere.html
http://www.journaldev.com/1061/java-synchronization-and-thread-safety-tutorial-with-examples
https://docs.oracle.com/javase/tutorial/essential/concurrency/atomicvars.html
Besides class "nodes" is not described here and classes are expected to start with an upper case letter.

Thread interrupt not ending blocking call on input stream read

I'm using RXTX to read data from a serial port. The reading is done within a thread spawned in the following manner:
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(port);
CommPort comm = portIdentifier.open("Whatever", 2000);
SerialPort serial = (SerialPort)comm;
...settings
Thread t = new Thread(new SerialReader(serial.getInputStream()));
t.start();
The SerialReader class implements Runnable and just loops indefinitely, reading from the port and constructing the data into useful packages before sending it off to other applications. However, I've reduced it down to the following simplicity:
public void run() {
ReadableByteChannel byteChan = Channels.newChannel(in); //in = InputStream passed to SerialReader
ByteBuffer buffer = ByteBuffer.allocate(100);
while (true) {
try {
byteChan.read(buffer);
} catch (Exception e) {
System.out.println(e);
}
}
}
When a user clicks a stop button, the following functionality fires that should in theory close the input stream and break out of the blocking byteChan.read(buffer) call. The code is as follows:
public void stop() {
t.interrupt();
serial.close();
}
However, when I run this code, I never get a ClosedByInterruptException, which SHOULD fire once the input stream closes. Furthermore, the execution blocks on the call to serial.close() -- because the underlying input stream is still blocking on the read call. I've tried replacing the interrupt call with byteChan.close(), which should then cause an AsynchronousCloseException, however, I'm getting the same results.
Any help on what I'm missing would be greatly appreciated.
You can't make a stream that doesn't support interruptible I/O into an InterruptibleChannel simply by wrapping it (and, anyway, ReadableByteChannel doesn't extend InterruptibleChannel).
You have to look at the contract of the underlying InputStream. What does SerialPort.getInputStream() say about the interruptibility of its result? If it doesn't say anything, you should assume that it ignores interrupts.
For any I/O that doesn't explicitly support interruptibility, the only option is generally closing the stream from another thread. This may immediately raise an IOException (though it might not be an AsynchronousCloseException) in the thread blocked on a call to the stream.
However, even this is extremely dependent on the implementation of the InputStream—and the underlying OS can be a factor too.
Note the source code comment on the ReadableByteChannelImpl class returned by newChannel():
private static class ReadableByteChannelImpl
extends AbstractInterruptibleChannel // Not really interruptible
implements ReadableByteChannel
{
InputStream in;
⋮
The RXTX SerialInputStream (what is returned by the serial.getInputStream() call) supports a timeout scheme that ended up solving all my problems. Adding the following before creating the new SerialReader object causes the reads to no longer block indefinitely:
serial.enableReceiveTimeout(1000);
Within the SerialReader object, I had to change a few things around to read directly from the InputStream instead of creating the ReadableByteChannel, but now, I can stop and restart the reader without issue.
i am using the code below to shutdown rxtx. i run tests that start them up and shut them down and the seems to work ok. my reader looks like:
private void addPartsToQueue(final InputStream inputStream) {
byte[] buffer = new byte[1024];
int len = -1;
boolean first = true;
// the read can throw
try {
while ((len = inputStream.read(buffer)) > -1) {
if (len > 0) {
if (first) {
first = false;
t0 = System.currentTimeMillis();
} else
t1 = System.currentTimeMillis();
final String part = new String(new String(buffer, 0, len));
queue.add(part);
//System.out.println(part + " " + (t1 - t0));
}
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
//System.out.println(Thread.currentThread().getName() + " interrupted " + e);
break;
}
}
} catch (IOException e) {
System.err.println(Thread.currentThread().getName() + " " + e);
//if(interruSystem.err.println(e);
e.printStackTrace();
}
//System.out.println(Thread.currentThread().getName() + " is ending.");
}
thanks
public void shutdown(final Device device) {
shutdown(serialReaderThread);
shutdown(messageAssemblerThread);
serialPort.close();
if (device != null)
device.setSerialPort(null);
}
public static void shutdown(final Thread thread) {
if (thread != null) {
//System.out.println("before intterupt() on thread " + thread.getName() + ", it's state is " + thread.getState());
thread.interrupt();
//System.out.println("after intterupt() on thread " + thread.getName() + ", it's state is " + thread.getState());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " was interrupted trying to sleep after interrupting" + thread.getName() + " " + e);
}
//System.out.println("before join() on thread " + thread.getName() + ", it's state is " + thread.getState());
try {
thread.join();
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " join interruped");
}
//System.out.println(Thread.currentThread().getName() + " after join() on thread " + thread.getName() + ", it's state is" + thread.getState());
}

Categories