Threading Wait During While Loop - java

My application has 1 global driver, which is responsible for doing the low-level work.
I then have 2 threads, both of which use infinite loops to get some work done. My question is how to allow 1 thread to use the driver as much as possible, but giving a chance to the second thread to use it when necessary.
To elaborate, the code I have is as follows:
public class Game {
private static final Object LOCK = new Object();
private static final Logger LOGGER = Logger.getLogger(Game.class);
private WebDriverController controller;
public Game(WebDriverController controler) {
this.controller = controller;
}
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
}
}
}).start();
}
public void startThreadB() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
...
...
synchronized (LOCK) {
controller.doSomethingB();
}
...
...
}
}
}).start();
}
}
The logic is to allow the first thread to execute doSomethingA() as much as possible, with the second thread only acquiring the lock to complete little tasks and then giving the lock back to the first thread.
Using this code, the first thread will continuously use the controller to do what it needs to do, whereas the second thread gets stuck waiting at its synchronized block. The way I have currently fixed this is by adding a pause to the first thread, to give the second thread a chance to acquire the lock, as follows:
public void startThreadA() {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (LOCK) {
controller.doSomethingA();
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
LOGGER.error(null, e);
}
}
}
}).start();
}
This does work exactly as intended, but it doesn't seem right. I'm not happy with the manual pause after each iteration, especially if the second thread does not need the lock as it's wasting time.
What do I replace the pause with to make this more efficient?

Why you use synchronized in run()? Use synchronized or Lock in your methods in WebDriverController.
public void doSomeThingA(){
lock.lock();
try {
//your stuff
} finally {
lock.unlock();
}
}
And in run method of Thread invoke these methods.

I think you are approaching this from the wrong direction, as in your current setup 99.999% of the time thread A calls for a monitor the processing time is wasted. However as I do not have enough details about your actual problem, here is a quick solution using a ReentrantLock with fair scheduling (FIFO):
protected final ReentrantLock lock = new ReentrantLock(true); // fair scheduling
public void functionA() {
lock.lock();
try {
controller.functionA();
} finally {
lock.unlock();
}
}
public void functionB() {
lock.lock();
try {
controller.functionB();
} finally {
lock.unlock();
}
}
Explanation:
If Thread A is currently holding the lock and Thread B calls, B is guaranteed to receive the monitor right after A releases it, even if A immediately (before any thread switch occurs) calls for it again.

There are a few options here. The best bet in this instance is likely to be remove the responsibility of deciding when to do work from the threads and instead, waiting for an event from a monitor to release the threads to do work. You can then schedule the work in whichever ratio is best suited to the purpose.
Alternatively, remove the lack of thread safety from your controller code.

Assuming that above thread organization is the best way to go for your particular case, your problem is that first thread holds the lock too long, thus starving the second one.
You can check if doSomethingA function really needs locked driver all the time while it is being executed (in most cases it doesn't), and if not split it into multiple smaller execution blocks, some of which hold the lock while other's don't. This will create more time for second thread to kick in when it needs to.
If that cannot be done then you really need to rethink your app, because you have created a resource bottleneck.

It looks like Thread.yield () is what you are looking for.

Related

Lock outside or inside Thread?

I'm learning thread safety and I can't seem to find a clear answer to a question when searching online.
What is the difference and the impacts between this:
synchronized (lock) {
new Thread () {
public void run() {
// critical section
}
}.start();
}
and this:
new Thread () {
public void run() {
synchronized (lock) {
// critical section
}
}
}.start();
To give you a context, I'm coding a small lab and the approach is 'one thread per request' so each time the method is called, either one of those above is executed to the 'critical section' is executed in it's own thread.
So having the lock inside or outside the Thread has an impact? Does each thread 'inherit' the lock or does it have to be within each thread to be fully thread-safe?
synchronizing just means that only one thread at a time can execute certain part of code
in the first example, only one thread at a time can create and start a new thread. but notice that you are not protecting the critical section (multiple threads can execute their "run" method simultaneously)
synchronized (lock) {
new Thread () {
public void run() {
// critical section
}
}.start();
}
in the second example, multiple threads can create and start a new thread, but only one thread at a time can execute the critical section (protected by "lock")
new Thread () {
public void run() {
synchronized (lock) {
// critical section
}
}
}.start();

Waking up a thread without risking to get blocked

I have a worker thread running indefinitely, which goes to sleep for one minute if there's nothing to do. Sometimes, another piece of code produces some work and wants to wake the worker thread immediately.
So I did something like this (code for illustration only):
class Worker {
public void run() {
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
if (hasWork()) {
doIt();
} else {
wait(60_000);
}
}
public synchronized wakeMeUpInside() {
notify();
}
}
What I dislike is having to enter the monitor only for waking something up, which means that the notifying thread may be delayed for no good reason. As the choices of native synchronization are limited, I thought I'd switch to Condition, but it has exactly the same problem:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called.
Here's a semaphore based solution:
class Worker {
// If 0 there's no work available
private workAvailableSem = new Semaphore(0);
public void run() {
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
// Try to obtain a permit waiting up to 60 seconds to get one
boolean hasWork = workAvailableSem.tryAquire(1, TimeUnit.MINUTES);
if (hasWork) {
doIt();
}
}
public wakeMeUpInside() {
workAvailableSem.release(1);
}
}
I'm not 100% sure this meets your needs. A few things to note:
This will add one permit each time wakeMeUpInside is called. Thus if two threads wake up the Worker it will run doIt twice without blocking. You can extend the example to avoid that.
This waits 60 seconds for work to do. If none is available it'll end up back in the run method which will send it immediately back to the step method which will just wait again. I did this because I'm assuming you had some reason why you wanted to run every 60 seconds even if there's no work. If that's not the case just call aquire and you'll wait indefinitely for work.
As per comments below the OP wants to run only once. While you could call drainPermits in that case a cleaner solution is just to use a LockSupport like so:
class Worker {
// We need a reference to the thread to wake it
private Thread workerThread = null;
// Is there work available
AtomicBoolean workAvailable = new AtomicBoolean(false);
public void run() {
workerThread = Thread.currentThread();
while (!shuttingDown()) {
step();
}
}
private synchronized void step() {
// Wait until work is available or 60 seconds have passed
ThreadSupport.parkNanos(TimeUnit.MINUTES.toNanos(1));
if (workAvailable.getAndSet(false)) {
doIt();
}
}
public wakeMeUpInside() {
// NOTE: potential race here depending on desired semantics.
// For example, if doIt() will do all work we don't want to
// set workAvailable to true if the doIt loop is running.
// There are ways to work around this but the desired
// semantics need to be specified.
workAvailable.set(true);
ThreadSupport.unpark(workerThread);
}
}

Safely pausing and resuming a thread

I want to create a thread to make some HTTP requests every few seconds and is easy to pause and resume at a moments notice.
Is the way below preferred, safe and efficient?
public class Facebook extends Thread {
public boolean running = false;
public void startThread() {
running = true;
}
public void stopThread() {
running = false;
}
public void run() {
while(true) {
while(running) {
//HTTP Calls
Facebook.sleep(2000);
}
}
}
}
Your Code:
In your example, the boolean should be volatile boolean to operate properly. The other issue is if running == false your thread just burns CPU in a tight loop, and you probably would want to use object monitors or a Condition to actually wait idly for the flag to become true again.
Timer Option:
I would suggest simply creating a Timer for this. Each Timer implicitly gets its own thread, which is what you are trying to accomplish.
Then create a TimerTask (FacebookTask below is this) that performs your task and from your main control class, no explicit threads necessary, something like:
Timer t;
void resumeRequests () {
if (t == null) { // otherwise its already running
t = new Timer();
t.scheduleAtFixedRate(new FacebookTask(), 0, 2000);
}
}
void pauseRequests () {
if (t != null) { // otherwise its not running
t.cancel();
t = null;
}
}
Note that above, resumeRequests() will cause a request to happen immediately upon resume (as specified by the 0 delay parameter); you could theoretically increase the request rate if you paused and resumed repeatedly in less than 2000ms. This doesn't seem like it will be an issue to you; but an alternative implementation is to keep the timer running constantly, and have a volatile bool flag in the FacebookTask that you can set to enable/disable it (so if it's e.g. false it doesn't make the request, but continues checking every 2000ms). Pick whichever makes the most sense for you.
Other Options:
You could also use a scheduled executor service as fge mentions in comments. It has more features than a timer and is equally easy to use; they'll also scale well if you need to add more tasks in the future.
In any case there's no real reason to bother with Threads directly here; there are plenty of great tools in the JDK for this job.
The suggestion to using a Timer would work better. If you want to do the threading manually, though, then something more like this would be safer and better:
class Facebook implements Runnable {
private final Object monitor = new Object();
public boolean running = false;
public void startThread() {
synchronized (monitor) {
running = true;
monitor.notifyAll();
}
}
public void stopThread() {
synchronized (monitor) {
running = false;
}
}
#Override
public void run() {
while(true) {
try {
synchronized (monitor) {
// Wait until somebody calls startThread()
while (!running) {
monitor.wait();
}
}
//HTTP Calls
Thread.sleep(2000);
} catch (InterruptedException ie) {
break;
}
}
}
}
Note in particular:
You should generally implement Runnable instead of subclassing Thread, then use that Runnable to specify the work for a generic Thread. The work a thread performs is not the same thing as the thread itself, so this yields a better model. It's also more flexible if you want to be able to perform the same work by other means (e.g. a Timer).
You need to use some form of synchronization whenever you want two threads to exchange data (such as the state of the running instance variable). There are classes, AtomicBoolean for example, that have such synchronization built in, but sometimes there are advantages to synchronizing manually.
In the particular case that you want one thread to stop work until another thread instructs it to continue, you generally want to use Object.wait() and a corresponding Object.notify() or Object.notifyAll(), as demonstrated above. The waiting thread consumes zero CPU until it is signaled. Since you need to use manual synchronization with wait/notify anyway, there would be no additional advantage to be gained by using an AtomicBoolean.
Edited to add:
Since apparently there is some confusion about how to use this (or the original version, I guess), here's an example:
class MyClass {
static void main(String[] args) {
FaceBook fb = new FaceBook();
Thread fbThread = new Thread(fb);
fbThread.start();
/* ... do stuff ... */
// Pause the FaceBook thread:
fb.stopThread();
/* ... do more stuff ... */
// Resume the FaceBook thread:
fb.startThread();
// etc.
// When done:
fbThread.interrupt(); // else the program never exits
}
}
I Would recommend you to use a guarded blocks and attach the thread to a timer

Java wait() does not get waked by notify()

Hallo I've been debugging my code for a whole day already, but I just can't see where could be wrong.
I use SerialPortEventListener on a main thread, in a working thread I have a client socket communicating to a server.
Since after this working thread reach return, I still need some wrap up work done in the main thread, i want to create a "pseudothread" that wait in the main thread until the it is notified from the listener onEvent method.
but this pseudothread seems to be waiting forever.
I checked the locked thread pseudoThread, they should have the same object id in the Runnable and in Listener class.
"PseudoThread waiting" got displayed, but PseudoThread awake is never showed.
Console output shows:
PseudoThread waiting
..
..
false notified pseudothread.
PS if I create a lock in Main class with public final Object lock = new Object(); and replace all main.pseudoThread with main.lock, I get java.lang.IllegalMonitorStateException.
private class Pseudo implements Runnable{
Main main;
public Pseudo(Main main) {
this.main = main;
}
#Override
public void run() {
synchronized(main.pseudoThread){
try {
System.out.println("PseudoThread waiting");
main.pseudoThread.wait();
System.out.println("PseudoThread awake");
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
}
}
}
in main method:
public static void main(String[] args) {
Main main = new Main();
main.initArduino();
//more code. including starting the working thread
main.pseudoThread = new Thread(main.new Pseudo(main));
main.pseudoThread.start();
try {
main.pseudoThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void initArduino() {
arduino = new Arduino(this);
if(!arduino.initialize())
System.exit(1);
}
and in the listener class (which also runs in main thread)
//class constructor;
public Arduino(Main Main){
this.main = Main;
}
//listening method
public void serialEvent(SerialPortEvent oEvent){
//some code to interract with working thread.
record();
}
private void record(){
synchronized(main.pseudoThread){
main.pseudoThread.notify();
System.out.println("notified pseudothread.");
}
}
Without looking too deeply into what might actually be happening, I can see that your use of wait()/notify() is all wrong. Probably you are experiencing a "lost notification." The notify() function does nothing if there is no thread waiting for it at the moment when it is called. If your serialEvent() function calls notify() before the other thread calls wait(), then the notification will be lost.
Consider this example:
class WaitNotify() {
private final Object lock = new Object();
private long head = 0;
private long tail = 0;
public void consumer() {
synchronized (lock) {
while(head == tail) {
lock.wait();
}
doSomething();
count head += 1;
}
}
public void producer() {
synchronized (lock) {
tail += 1;
lock.notify();
}
}
}
The essential points are:
(1) The consumer() function waits for some relationship between data to become true: Here, it waits for head != tail.
(2) The consumer() function waits in a loop. There's two reasons for that: (a) Many programs have more than one consumer thread. If consumer A wakes up from the wait(), there's no guarantee that consumer B hasn't already claimed whatever it was that they both were waiting for. And (b) The Java language spec allows foo.wait() to sometimes return even when foo.notify() has not been called. That's known as a "spurious wakeup." Allowing spurious wakeups (so long as they don't happen too often) makes it easier to implement a JVM.
(3) The lock object is the same lock that is used by the program to protect the variables upon which the condition depends. If this example was part of a larger program, you would see synchronized(lock) surrounding every use of head and tail regardless of whether the synchronized code is wait()ing or notify()ing.
If your own code obeys all three of the above rules when calling wait() and notify(), then your program will be far more likely to behave the way you expect it to behave.
As suggested by james it could be lost notification case or it could be that.. Two Threads 1- Your Main Thread and 2- Pseudo thread Are waiting on the same Thread Instance Lock (main.pseudoThread)( Main thread waits on the same lock by calling join method).
Now you are using notify which wakes the Main thread from join method and not the one
waiting in your Pseudo. To check for the second case try calling notifyall in record this will either
confirm the second case or will rule this possibility.
Anyways please refactor your code not to use synch on Thread instance its bad practice. Go for ReentrantLock or CoundDownLatch something.
Usage of notify and wait seem to be incorrect. Method name notify can be a bit misleading because it is not for general purpose "notifying". These methods are used to control the execution of synchronization blocks. Wait will allow some other thread to synchronize with same object while current threads pauses. Basically this is used when some resource is not available and execution can not continue. On the other hand notify will wake one waiting thread wake from wait after notifying thread has completed its synchronized-block. Only one thread can be in synchronized block of the same object at the same time.
If the idea is just keep the main program running until notified then semaphore would be much more appropriate. Something like this.
public void run() {
System.out.println("PseudoThread waiting");
main.semaphore.acquireUninterruptibly();
System.out.println("PseudoThread awake");
}
//...
private void record(){
main.semaphore.release();
}
//...
public static void main(String[] args) {
main.semaphore = new Semaphore(0);
//...
}

Why does the following code result in thread contention

I have the following code
public class Test {
Lock lock = new ReentrantLock();
public static void main(String args[]) throws Exception {
Test t = new Test();
Second second = t.new Second();
second.lock = t.lock;
Thread thread = new Thread(second);
thread.start();
Thread.sleep(2000);
try {
t.lock.lock();
System.err.println("got the lock");
} finally {
second.shutdown = true;
t.lock.unlock();
}
}
private class Second implements Runnable {
Lock lock;
volatile boolean shutdown = false;
int i = 0;
public void run() {
while (!shutdown) {
try {
lock.lock();
System.out.println("In second:" + i++);
} finally {
lock.unlock();
}
}
}
}
}
I read here that there is a concept of fair and unfair lock, but making locks fair has a big performance impact and nevertheless shouldn't the above code give some fairness to the current thread.
While actual execution of the above code, the second thread runs forever (gave way for main thread after 545342 iterations)
Is there something I am doing wrong here? Can anyone explain this behavior?
Basically without making the lock fair, the second thread is unlocking and managing to reacquire the lock before the first thread gets a chance to do so. After your large number of iterations, it must have been pre-empted between the "unlock" and the "lock", giving your first thread an opportunity to get in and stop it.
Fundamentally though, you simply shouldn't have code like that in the second thread - under what real life situation do you want to repeatedly release and acquire a lock doing no work between the two, beyond checking a flag? (And if you do want to do that, why do you want to require that a "shutting down" thread acquires the same lock in order to set the flag?)

Categories