I have this Transmitter class, which contains one BufferedReader and one PrintWriter. The idea is, on the main class, to use Transmitter.receive() and Transmitter.transmit() to the main socket. The problem is:
public void receive() throws Exception {
// Reads from the socket
Thread listener = new Thread(new Runnable() {
public void run() {
String res;
try {
while((res = input.readLine()) != null) {
System.out.println("message received: " + res);
outputMessage = (res);
if (res.equals("\n")) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
};
});
listener.start();
listener.join();
}
The thread changes the 'outputMessage' value, which I can get using an auxiliary method. The problem is that, without join, my client gets the outputMessage but I want to use it several times on my main class, like this:
trans1.receive();
while(trans1.getOutput() == null);
System.out.println("message: " + trans1.getOutput());
But with join this system.out never executes because trans1.receive() is stuck... any thoughts?
Edit 1: here is the transmitter class https://titanpad.com/puYBvlVery
You might send \n; that doesn't mean that you will see it in your Java code.
As it says in the Javadoc for BufferedReader.readLine() (emphasis mine):
(Returns) A String containing the contents of the line, not including any line-termination characters
so "\n" will never be returned.
Doing this:
{
Thread listener = new Thread(new Runnable() {
public void run() {
doSomeWork();
};
});
listener.start();
listener.join();
}
will create a new thread and then wait for it to do its work and finish. Therefore it's more or less the same as just directly doing:
doSomeWork();
The new thread doesn't serve any real purpose here.
Also, the extra thread introduces synchronization problems because in your code you don't make sure your variables are synchronized.
Thirdly, your thread keeps reading lines from the input in a loop until there's nothing more to read and unless the other side closes the stream, it will block on the readLine() call. What you will see in with getOutput() will be a random line that just happens to be there at the moment you look, the next time you look it might be the same line, or some completely different line; some lines will be read and forgotten immediatelly without you ever noticing it from the main thread.
You can just call input.readLine() directly in your main thread when you actually need to get a new line message from the input, you don't need an extra reader thread. You could store the read messages into a Queue as yshavit suggests, if that's desirable, e.g. for performance reasons it might be better to read the messages as soon as they are available and have them ready in memory. But if you only need to read messages one by one then you can simply call input.readLine() only when you actually need it.
Related
I'm building an interactive LED table with a 14x14 matrix consisting of addressable LED strips for an university assignment. Those are being controlled by 2 arduinos that get the data about which LED should have which RGB value from a Pi running a server that runs several games which should be playable on the LED table. To control the games I send respective int codes from an android app to the server running on the Raspi.
The serial communication is realized by using jSerialComm. The problem I'm facing is, that I don't want to permanently send data over the serial port but only at the moment, when a new array that specifies the matrix is available.
Therefore I don't want to be busy waiting and permanently checking if the matrix got updated not do I want to check for a update with
while(!matrixUpdated) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
So what I've been trying was running a while(true) in which I call wait(), so the thread stops until I wake the thread up by calling notify when an updated matrix is available.
My run() method in the serial thread looks like this at the moment:
#Override
public void run() {
arduino1.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
arduino2.setComPortTimeouts(SerialPort.TIMEOUT_SCANNER, 0, 0);
try {
Thread.sleep(100);
} catch (Exception e) {}
PrintWriter outToArduino1 = new PrintWriter(arduino1.getOutputStream());
PrintWriter outToArduino2 = new PrintWriter(arduino2.getOutputStream());
while(true) {
try {
wait();
} catch (InterruptedException e) {}
System.out.println("Matrix received");
outToArduino1.print(matrix);
outToArduino2.print(matrix);
}
}
I wake the thread up by this method which is nested in the same class:
public void setMatrix(int[][][] pixelIdentifier) {
matrix = pixelIdentifier;
notify();
}
I also tried notifyAll() which didn't change the outcome.
In one of the games (Tic Tac Toe) I call this method after every game turn to update and send the matrix to the arduinos:
private void promptToMatrix() {
synchronized (GameCenter.serialConnection) {
GameCenter.serialConnection.setMatrix(matrix);
}
}
I previously called it without using the synchronized block but as I've been reading through many articles on that topic on StackOverflow I have read that one should use synchronized for this. Further I have also read that using wait() and notify() is not recommended, however as the assignment needs to get done quite quickly I don't know if any other approach makes sense as I don't want to restructure my whole application as I run up to 5 threads when a game is being played (due to threads for communication and so on).
If there is a possibility to solve this using wait() and notify() I would be really grateful to hear how that would be done, as I have not been able to really comprehend how working properly with the synchronized block is being done and so on.
However if such a solution is not possible or would also end in restructuring the whole application I'm also open to different suggestions. Pointing out that using wait() and notify() is not recommended however doesn't help me, as I've already read that often enough, I'm aware of that but prefer to use it in that case if possible!!!
EDIT:
The application executes like this:
Main Thread
|--> SerialCommunication Thread --> waiting for updated data
|--> NetworkController Thread
|--> Client Thread --> interacting with the game thread
|--> Game Thread --> sending updated data to the waiting SerialCommunication Thread
Really appreciate any help and thanks in advance for your time!
You are dealing with asynchronous update possibly running on different threads, the best match in my opinion is using RxJava.
You could use a Subject to receive matrix event and then subscribe to it to update the leds.
You can write something like this (don't take it too literally).
public static void main(String[] args) {
int[][] initialValue = new int[32][32];
BehaviorSubject<int[][]> matrixSubject = BehaviorSubject.createDefault(initialValue);
SerialPort arduino1 = initSerial("COM1");
SerialPort arduino2 = initSerial("COM2");;
PrintWriter outToArduino1 = new PrintWriter(arduino1.getOutputStream());
PrintWriter outToArduino2 = new PrintWriter(arduino2.getOutputStream());
Observable<String> serializedMatrix = matrixSubject.map(Sample::toChars);
serializedMatrix.observeOn(Schedulers.io()).subscribe(mat -> {
// Will run on a newly created thread
outToArduino1.println(mat);
});
serializedMatrix.observeOn(Schedulers.io()).subscribe(mat -> {
// Will run on a newly created thread
outToArduino2.println(mat);
});
// Wait forever
while(true) {
try {
// get your matrix somehow ...
// then publish it on your subject
// your subscribers will receive the data and use it.
matrixSubject.onNext(matrix);
Thread.sleep(100);
} catch (InterruptedException e) {
// SWALLOW error
}
}
}
public static String toChars(int[][] data) {
// Serialize data
return null;
}
There are may operators that you could use to make it do what you need, also you can use different schedulers to choose from different thread policies.
You can also transform your input in the subject you publish, an observable or a subject can be created directly from your input.
I have an application that, among other things, runs Java methods via java.lang.reflect. It normally functions as normal; however, a user used it with one of their JARs, and it broke somewhat.
As you can see in the below code, I attempt to capture both stdout and stdin from the method. However, when the method is invoked, only the first line of what the method streams to stdout is actually captured.
Here's the relevant code. If you need to see more of the code, let me know, and I'll add some more:
String retVal = "";
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayOutputStream err = new ByteArrayOutputStream();
PrintStream origOut = System.out;
PrintStream origErr = System.err;
System.setOut(new PrintStream(out));
System.setErr(new PrintStream(err));
Exception myException = null;
try {
Object myRetVal = null;
myRetVal = m.invoke(obj, convertedMethodArguments);
if (myRetVal != null)
retVal = myRetVal.toString();
} catch (Exception e) {
myException = e;
}
returnObj.addProperty("stdout", out.toString());
returnObj.addProperty("stderr", err.toString());
returnObj.addProperty("rv", retVal);
returnObj.addProperty("rt", m.getReturnType().toString());
if (myException != null && myException.getCause() != null)
returnObj.addProperty("exception", myException.getCause().toString());
else
returnObj.addProperty("exception", "");
System.setOut(origOut);
System.setErr(origErr);
System.out.print(new Gson().toJson(returnObj));
// TODO: remove, debug purposes only
// Should use normal stdout
try {
System.out.println();
m.invoke(obj, convertedMethodArguments);
} catch (Exception e) {
System.out.println(e.toString());
}
When I execute the above code, it only prints out the first line of stdout. However, at the bottom of the code block, I invoke the method again, but this time without any redirection, and I get all of the stdout from the method.
Any help would be greatly appreciated!
EDIT #1: OK, get this. For fun, I commented-out the two lines where I redirect the default System streams (e.g. System.setOut and System.setErr). With these gone, I now expect all stdout to be written to the console directly when I run the app.
I added a message (e.g. System.out.println("Testing...");) at the very end of my code, so that it's the last thing that is executed. When I test the app, I get the first line of stdout, followed by my testing message, and THEN the rest of the stdout.
I have no clue what's going on here.
EDIT #2: Per #Titus's suggestion, I looked into whether or not the method I'm invoking is spinning off its own threads. Turns out, it is. Two threads are created, AWT-AppKit and AWT-Shutdown. The former thread seems to stay in RUNNABLE state, whereas the latter thread stays in the TIMED_WAITING state.
Over time, the AWT-Shutdown thread goes away, but the other one stays alive in its RUNNABLE state. Once my application exits, I believe the method I'm invoking also exits, and at that point the extra messages are displayed to the screen (which explains why I can't capture this bit of STDOUT).
What I don't understand is why this method won't terminate within my application.
Try to flush the streams after you call the method.
Here is an example:
PrintStream outPR = new PrintStream(out);
System.setOut(outPR);
....
outPR.flush();
returnObj.addProperty("stdout", out.toString());
You can even do this:
System.setOut(new PrintStream(out, true));
....
System.out.println();
returnObj.addProperty("stdout", out.toString());
The PrintStream is automatically flushed (if you use the constructor that I've used) when a \n (new line) is written to it.
Based on the edits to your question, it is possible that the method you're calling is creating new threads which means that it is possible that this new threads print to the console after the method returns.
If that is the case, you'll have to wait until this threads finish in order to get all the output.
I changed System.out to print to a file, by invoking System.setOut and System.setErr.
Every night at midnight, we want to rename (archive) the current log file, and create a new one.
if (out != null) {
out.close();
out = null;
File f = new File(outputfilename);
f.renameTo(new File(dir.getPath().replace(".log", "-" + System.currentTimeMillis() + ".log")))
StartLogFile();
}
The StartLogFile():
if (out == null) {
out = new FileOutputStream(outputfilename, true);
System.setOut(new PrintStream(out));
System.setErr(new PrintStream(out));
}
I've left exception-handling out.
My concern is that if something tries to print in between out.close() and setOut/setErr that I'm going to miss a log.
My real question is, how can I make this atomic with other calls to System.out.println?
I was thinking about trying
synchronized (System.out) {
}
but I'm not actually sure if the intrinsic lock here does anything. Especially since I'm nullifying the out object during the operation.
Does anyone know how I can ensure proper synchronization here?
I would create the new out before closing the old one:
PrintStream old = System.out;
out = new FileOutputStream(outputfilename, true);
System.setOut(new PrintStream(out));
old.close();
This way the old PrintStream is not closed until the new one is created and assigned. At all times there is a valid PrintStream in System.out.
There is no need for synchronized block, because everything is in the same thread.
Yes you can achieve proper synchronization that way. Here is a sample test.
#Test
public void test() throws InterruptedException {
new Thread(()->{
while(true){
System.out.println("printing something");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}).start();
Thread.sleep(500);
synchronized (System.out){
System.out.println("changin system out");
Thread.sleep(2000);
System.out.println("finished with sysout");
}
Thread.sleep(2000);
}
and the output will be:
printing something
printing something
printing something
printing something
printing something
changin system out
finished with sysout
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
printing something
There is no way to make this work safely, since you have no control what the calling code is doing with System.out. Think of this:
public void doSomethingTakingALongTime(PrintStream target) {
// lots of code
}
// somewhere else
doSomethingTakingALongTime(System.out);
You can never be sure there isn't a copy of System.out reference somewhere out there in a local variable or method parameter.
The proper way to solve this would be to set System.out only once, at the very start of the program, and instead of using a standard PrintStream, you use your own implementation that delegates everything to the current target.
You are then in complete control of every output made through System.out and can synchronize at you leisure where required. If your own implementation synchronizes every operation, the question of what happens while you're changing the logging target doesn't even arise - every other caller will simply be blocked by the synchronization lock.
Btw. its questionable to use System.out for logging. The de-facto standard for logging would be using log4j. Consider switching to that.
Edit: Actually implementing this delegation can be rather easy. There is a constructor PrintStream(OutputStream). That means you can just implement delegation in an OutputStream (that has considerably less methods than PrintStream) and set System.out to your new PrintStream(YourRetargettingOutputStream).
You can define an object explicitly for locking like
static final Object lock = new Object();
How about locking over it like below
synchronized(lock){
if(out != null) {
out.close();
out = null;
File f = new File(outputfilename);
f.renameTo(new File(dir.getPath().replace(".log", "-" + System.currentTimeMillis() + ".log")))
StartLogFile();
}
}
The problem is: there are two threads, one is a writer to a List another is a reader from the List. Sometimes reader gets stuck if loop in the writer has large amount of iterations. That reader in that case becomes Blocked (not Waiting), which means that it received notification, but writer did not released monitor?
So, why so?
What is the best to do with this? (is sleep fine?)
import java.util.LinkedList;
import java.util.List;
public class Main {
private List<Object> m_calls = new LinkedList<Object>();
public void startAll(){
Thread reader = new Thread(new Runnable() {
#Override
public void run() {
while(true){
synchronized(m_calls){
while (m_calls.size() == 0) {
try {
System.out.println("wait");
m_calls.wait();
} catch (InterruptedException e) {
return;
}
}
m_calls.remove(0);
System.out.println("remove first");
}
}
}
});
Thread writer = new Thread(new Runnable() {
#Override
public void run() {
for(int i = 0; i < 15; i++){
// UN-comment to have more consistent behavior
/*try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
synchronized(m_calls){
m_calls.add(new Object());
m_calls.notifyAll();
System.out.println("sent");
}
}
}
});
reader.start();
writer.start();
}
public static void main(String[] args) {
new Main().startAll();
}
}
Running of the code above gives different results:
---------------------------------- 1st attempt
wait
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
remove first
wait
---------------------------------- 2nd attempt
wait
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
wait
sent
sent
remove first
remove first
wait
sent
sent
sent
sent
sent
sent
sent
remove first
remove first
remove first
remove first
remove first
remove first
remove first
wait
------------------------------ Uncommented sleep() - works us expected
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
sent
remove first
wait
Edit 1: The reader thread (one of them) seems to be not waiting any more, rather it's blocked, which looks like its monitor received notification (after notifyAll()) but writer thread do not release lock in its loop, what is confusing...
Your particular situation would be better done using a BlockingQueue. Blocking queues will block the take thread (the reader) until something is put in the queue (by a writer).
Here's your modified code using a blocking queue:
public class Main {
private BlockingQueue<Object> m_calls = new LinkedBlockingQueue<Object>();
public void startAll(){
Thread reader = new Thread(new Runnable() {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
Object obj = m_calls.take();
System.out.println("obj taken");
} catch(InterruptedException ex) {
// Let end
}
}
}
});
Thread writer = new Thread(new Runnable() {
#Override
public void run() {
try {
for(int i = 0; i < 15; i++){
m_calls.put(new Object());
System.out.println("obj put");
}
} catch (InterruptedException ex) {
// Let end
}
}
});
reader.start();
writer.start();
}
public static void main(String[] args) {
new Main().startAll();
}
}
The output:
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
obj put
obj taken
This will be much safer than a) using a plain LinkedList and b) trying to use your own wait/notify. Your wait/notify was also pretty vulnerable to race conditions. If the writer thread called notify before the reader called wait, then the reader could wait indefinitely on the last entry.
I might also add that this solution is safe for multiple reader and writer threads. Multiple threads can put and take all at the same time, and the LinkedBlockingQueue will handle the concurrency for you.
The only thing to be careful about is if Object accesses some shared resource, but this is another problem that's related to concurrent access of a group of objects. (Along the lines of "can I access obj1 and obj2 at the same time from two different threads?") This is another problem entirely, so I won't detail a solution here.
Its worth nothing that nothing happens immediately and when it comes to threads, you cannot be sure when independent events happen. (Which one of the reasons synchronisation is required)
final long start = System.nanoTime();
new Thread(new Runnable() {
#Override
public void run() {
System.out.printf("Took %,d ns to start this thread%n", System.nanoTime() - start);
}
}).start();
prints
Took 2,807,336 ns to start this thread
This might not sounds like a long time, but at 3.2 GHz this is almost 9 million clock cycle. A computer can do an awful lot in that time. In your case, a short lived thread can run to completion before the second thread even starts.
In the second case, what you are seeing is that locking is not fair (i.e. fair means the one waiting the longest gets the lock first) The reason for this is it is much slower to implement this properly e.g. 10x slower or more. For this reason, a lock tends to be given the the thread which has it last as this is far more efficient in most cases.
You can get fair locks using Lock lock = new ReentrantLock(true); but this is generally not used unless required as it is slower for little gain most of the time.
You can try -XX:-UseBiasedLocking to make locking slightly fairer.
To do much the same thing with ExecutorService you can code it like
ExecutorService service = Executors.newSingleThreadExecutor();
// writer
for (int i = 0; i < 15; i++) {
service.submit(new Runnable() {
#Override
public void run() {
// reader
System.out.println("remove first");
}
});
System.out.println("sent");
}
service.submit(new Runnable() {
#Override
public void run() {
System.out.println("wait");
}
});
service.shutdown();
prints
sent
remove first
sent
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
sent
remove first
remove first
wait
A better way to synchronize in such szenarios is to use java.util.concurrent.* in your case perhaps a CountDownLatch.
Maybe try this first before looking for a reason for the deadlock.
EDIT: And Peter is right. It seems to be running ok?
EDIT 2: OK, whole different story after the additional info.
I suggest you work with timeouts to force at least one try in reading even if there is more to write after a certain timespan.
wait even has a version with timeout ... http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#wait(long)
But again: personally I'd prefer using the concurrancy API.
I have an application that is redirecting my System.out text to a Jtextarea. This works fine but when I call one of the methods in my application is creates multiple threads and uses a latch counter to wait for them to finish. That method then calls latch.await() so that it does not finish running its code until the other threads are finished. The problem is that once the latch.await() code is called my JtextArea stops posting text until all the threads have finished. Any ideas around this? Eclipse console is able to keep posting while the latch.await() is running so it has to be possible.
Example:
From the GUI:
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("You pressed Start");
MyGoogleSearch startParsing = new MyGoogleSearch();
try {
startParsing.startParser(othoSelection); ...
MyGoogleSearch:
Enumeration e = hm.elements();
//Read in src/Ontology/Ontology.txt
//Put each line into the searchQuery ArrayQueue
while ((strLine = br.readLine()) != null)
{
searchQuery.put(strLine);
}
System.out.println("Finsihed loading");
//Create 32 threads (More threads allows you to pull data from Bing faster. Any more than 32 and Bing errors out (you start to pull data
//too fast)
for(int i = 0; i < 32; i++)
{
System.out.println("Starting thread: " + i);
new NewThread();
}
//Wait for all of the threads to finish
latch.await();
e = hm.keys();
//Write the URL's from the hashmap to a file
while (e.hasMoreElements())
{
out.write(e.nextElement() + "\n");
}
//close input/output stream
in.close();
out.close();
System.out.println("Done");
and the Thread does some stuff then
MyGoogleSearch.latch.countDown();
This works fine but when I call one of the methods in my application is creates multiple threads and uses a latch counter to wait for them to finish.
You could get around that by calling the method in a separate thread. However, I suspect the method is waiting for all the threads to complete because it wants to aggregate some results and then return the aggregated result (or something similar). If that's the case, then there are several ways to deal with it, but probably the one that will make the most sense for a graphical application is to have the thread invoke a callback with any results which were obtained from the method.
If you post some sample code, then we can provide you with more specific answers and examples of how to do it.
Update:
I'm having a hard time reading your code, but I presume that 'startParser' is the call that's blocking. Additionally, it doesn't appear that the UI needs to wait for the results so I would recommend you do the simplest thing possible:
MyGoogleSearch startParsing = new MyGoogleSearch();
Thread t = new Thread(new Runnable(){
public void run(){
startParsing.startParser(othoSelection);
}
}
// don't wait for this thread to finish
t.start();