AbstractQueuedSynchronizer.acquireShared waits infinitely even that waiting condition has changed - java

I wrote a simple class that uses AbstractQueuedSynchronizer. I wrote a class that represents a "Gate", that can be passed if open, or is blocking if closed. Here is the code:
public class GateBlocking {
final class Sync extends AbstractQueuedSynchronizer {
public Sync() {
setState(0);
}
#Override
protected int tryAcquireShared(int ignored) {
return getState() == 1 ? 1 : -1;
}
public void reset(int newState) {
setState(newState);
}
};
private Sync sync = new Sync();
public void open() {
sync.reset(1);
}
public void close() {
sync.reset(0);
}
public void pass() throws InterruptedException {
sync.acquireShared(1);
}
};
Unfortunately, if a thread blocks on pass method because gate is closed and some other thread opens the gate in meantime, the blocked one doesn't get interrupted - It blocks infinitely.
Here is a test that shows it:
public class GateBlockingTest {
#Test
public void parallelPassClosedAndOpenGate() throws Exception{
final GateBlocking g = new GateBlocking();
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(2000);
g.open();
} catch (InterruptedException e) {
}
}
});
t.start();
g.pass();
}
}
Please help, what should I change to make the gate passing thread acquire the lock successfully.

It looks like setState() only changes the state, but doesn't notify blocked threads about the change.
Therefore you should use acquire/release methods instead:
#Override
protected boolean tryReleaseShared(int ignored) {
setState(1);
return true;
}
...
public void open() {
sync.releaseShared(1);
}
So, overall workflow of AbstractQueuedSynchronizer looks like follows:
Clients call public acquire/release methods
These methods arrange all synchronization functionality and delegate actual locking policy to protected try*() methods
You define your locking policy in protected try*() methods using getState()/setState()/compareAndSetState()

Related

Why stopping a SwingWorker does stop it immediately?

I'm using a SwingWorker to execute some repeatable tasks in background.
This is my Class:
public class CMyThread {
private SwingWorker<Object, Void> taskWorker;
public volatile boolean threadDone = false;
public CMyThread() {
}
#Override
public void stop() {
taskWorker.cancel(true);
}
#Override
public void start() {
taskWorker = new SwingWorker<Object, Void>() {
#Override
public Object doInBackground() {
while (!isCancelled()) {
// SOMETHING TIMECONSUMING THAT NEEDS TO BE DONE REPEATEDLY
CUtils.sleep(10000);
}
threadDone = true;
return null;
}
#Override
public void done() {
}
};
taskWorker.execute();
}
public void waitThreadToGentlyFinish() { // called when we call destroy() on the servlet
while (!threadDone) {
System.out.print("#");
CUtils.sleep(200);
}
}
}
And this is called this way:
CMyThread myThread = new CMyThread();
myThread.start();
Now, at one point I want to gently stop the thread.
So I call
myThread.stop();
myThread.waitThreadToGentlyFinish();
I'm expecting that the currently running [ACTION] is going to take time to finish, then only it will exit the loop and set the flag 'threadDone' to true. but what I actually see is that it exits the loop immediately and I never see any '#' characters displayed.
There is obviously something wrong in my code but I can't see the obvious.
Any idea guys ?

Java monitoring an object with another object

I would like to say that I tried to find some answers on this site but I couldn't manage, also this is my first question so I am sorry if i wrote it off format etc...
I am trying to learn java and now trying to understand thread section. So far I understood some basics and I wanted to try this: a lieutenant class shares the monitor-lock with a soldier class but I am failing at somewhere.
Edit: I want to Lieutenant waits until the Soldier says his first line, then he gives an order. But when soldier tries to release lock I get an monitor error because of notify method.
"Exception in thread "Thread-1" java.lang.IllegalMonitorStateException."
P.S: I know there are easier ways but I am trying to utilize wait&notify.
public class Lieutenant {
private boolean waitForCommand = true;
public void setWaitForCommand(boolean waitForCommand) {
this.waitForCommand = waitForCommand;
}
public synchronized void giveOrder() {
while (waitForCommand) {
try {
wait();
} catch (InterruptedException e) {
e.getStackTrace();
}
System.out.println("I said run soldier! RUN!");
}}}
public class Soldier {
private final Lieutenant lieutenant;
public Soldier(Lieutenant lieutenant) {
this.lieutenant = lieutenant;
}
public void getOrder() {
synchronized (this.lieutenant) {
System.out.println("Sir! Yes, sir!");
lieutenant.setWaitForCommand(false);
notifyAll();
}}}
class Main {
public static void main(String[] args) {
Lieutenant lieutenant = new Lieutenant();
Soldier soldier = new Soldier(lieutenant);
new Thread(new Runnable() {
#Override
public void run() {
lieutenant.giveOrder();
}}).start();
new Thread(new Runnable() {
#Override
public void run() {
soldier.getOrder();
}}).start();
}}
The immediate problem here is with this method:
synchronized (this.lieutenant) {
System.out.println("Sir! Yes, sir!");
lieutenant.setWaitForCommand(false);
notifyAll();
}}
The synchronized block is holding a lock on this.lieutenant but you are attempting to call notifyAll() on this, which you aren't holding the lock on.
If make this change
synchronized (this.lieutenant) {
System.out.println("Sir! Yes, sir!");
lieutenant.setWaitForCommand(false);
this.lieutenant.notifyAll();
}}
It should work better. But as mentioned in the comments you can't guarantee that giveOrder will be called before getOrder.

Trying to write a class that allows to do something before the Thread starts and after the Thread finishes

I am trying to write a Utility class that helps to execute a task on a Separate Thread, providing the ability to do something before the task starts, and something after the task ends.
Something similar to android's AsyncTask
Here is such a class.
class MySync
{
public void preExecute() {}
public void executeInBackground() {}
public void postExecute() {}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.preExecute();
MySync.this.executeInBackground();
MySync.this.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Here is how this class is supposed to be used. Consumer of the class will override the methods as per the requirement.
class RegisterStudent extends MySync
{
#Override
public void preExecute()
{
System.out.println("Validating Student details. Please wait...");
try
{
Thread.sleep(2000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void executeInBackground()
{
System.out.println("Storing student details into Database on Server. Please wait...");
try
{
Thread.sleep(4000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
#Override
public void postExecute()
{
System.out.println("Student details saved Successfully.");
}
}
And finally starting the task:
public class AsyncDemo
{
public static void main(String... args)
{
new RegisterStudent().execute();
}
}
It seems to work fine. My question is, is this the correct way of achieving the Objective as mentioned in the Title? Any suggestions on how best this can be implemented?
What I don't like with your approach is the fact that you create a new thread each time you create a new instance of MySync which is not scalable if you intend to create a lot of instances of your Object moreover it is costly to create a Thread, if I were you I would use an executor in order to limit the total amount of threads allocated to execute your tasks asynchronously, here is how you can do it if you want to use only one thread:
ExecutorService executor = Executors.newFixedThreadPool(1);
I would also re-write your code for something like this:
public abstract class MySync implements Runnable {
#Override
public final void run() {
try {
preExecute();
executeInBackground();
} finally {
postExecute();
}
}
protected abstract void preExecute();
protected abstract void executeInBackground();
protected abstract void postExecute();
}
This way you define the whole logic for all the implementations.
Then you can submit your task like this:
executor.submit(new RegisterStudent());
What's bad about this is that you're forcing users to extend your class. In java you can only extend 1 class. So a framework should not take that away.
Rather use an interface:
public interface AsyncTask {
public default void preExecute() {}
public default void executeInBackground() {}
public default void postExecute() {}
}
And have users pass that to your utility class:
class MySync
{
private AsyncTask task;
public MySync(AsyncTask task) {
this.task = task;
}
public final void execute()
{
threadExecute.start();
}
private final Thread threadExecute = new Thread()
{
#Override
public void run()
{
try
{
MySync.this.task.preExecute();
MySync.this.task.executeInBackground();
MySync.this.task.postExecute();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
};
}
Loader is exactly what you are looking for.
Here is introduction for loader
https://developer.android.com/guide/components/loaders.html
https://developer.android.com/reference/android/content/Loader.html

Stopping and resuming infinite loop on key input

Let's say we have an infinite loop, and we want to put it to sleep for a while, and then resume it. Instead of having a set time, we resume it when we press a key.
For example, in Java we could have:
while(true){
doSomething();
}
Now, we could make this interruptable in many ways. We want to interrupt it on a key press, so we will have:
boolean running = true;
...
this.addKeyListener(this);
...
#override
public void keyPressed(KeyEvent e){
running = false;
}
And then run a method (let's say run), which contains:
while(running){
doSomething();
}
But then we'd meet one problem: resuming.
So we take the keyPressed method, and change it's body to:
running = !running;
if(running){
run();
}
There is just one problem here: the KeyListener won't do anything until the run method is finished. I've tried using threads, where we would have:
private class Runner implements Runnable {
#Override
public void run() {
while (running) {
doSomething();
}
}
}
and in keyPressed:
if(running){
runner.wait();
}else{
runner.notify();
runner.run();
}
running = !running;
but in my actual code the doSomething method is code that can't be interrupted (because it handles output to the screen), so thread.wait() can never be called (it will throw exceptions all the time and not actually wait).
So then, to summarize: How does one stop and resume looping something at will using key input in Java?
wait and notify are intended to be called from different threads. As the name implies, wait should be called in the thread which is paused and waiting to be notified that a condition has changed:
private final Object keyPressMonitor = new Object();
private boolean running = true;
private Runnable gameLoop = new Runnable() {
#Override
public void run() {
try {
synchronized (keyPressMonitor) {
while (true) {
while (!running) {
keyPressMonitor.wait();
}
doSomething();
}
}
} catch (InterruptedException e) {
logger.log(Level.INFO,
"Interrupted; cleaning up and exiting.", e);
}
}
};
The other thread, presumably the AWT Event Dispatch Thread which is where your KeyListener (or Action invoked by an ActionMap/InputMap binding) is called, would notify the looping thread that the proper key has been pressed or released:
public void keyPressed(KeyEvent event) {
if (event.getKeyCode() == theKeyICareAbout) {
synchronized (keyPressMonitor) {
running = true;
keyPressMonitor.notifyAll();
}
}
}
public void keyReleased(KeyEvent event) {
if (event.getKeyCode() == theKeyICareAbout) {
synchronized (keyPressMonitor) {
running = false;
keyPressMonitor.notifyAll();
}
}
}
You can use Semaphore for these purposes:
private static class Runner implements Runnable {
private final AtomicInteger permits = new AtomicInteger(0);
private final Semaphore semaphore = new Semaphore(1, true);
private volatile boolean running;
public void putToSleep() {
semaphore.acquireUninterruptibly();
}
public void resume() {
semaphore.release(permits.getAndSet(0));
}
#Override
public void run() {
while (running) {
semaphore.acquireUninterruptibly(Integer.MAX_VALUE);
semaphore.release(Integer.MAX_VALUE);
doSomething();
}
}
private void doSomething() {
//...
}
}

Create a java thread that runs on a timer but can be awaken at any time

I would like to create a class that runs something (a runnable) at regular intervals but that can be awaken when needed. If I could encapsulate the whole thing I would like to expose the following methods:
public class SomeService implements Runnable {
public run() {
// the code to run at every interval
}
public static void start() { }
public static void wakeup() { }
public static void shutdown() { }
}
Somehow I've gotten this far. But I'm not sure if this is the correct approach.
public class SomeService implements Runnable {
private static SomeService service;
private static Thread thread;
static {
start();
}
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
synchronized (thread) {
try {
thread.wait(15000);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void start() {
System.out.println("start");
service = new SomeService();
thread = new Thread(service);
thread.setDaemon(true);
thread.start();
}
public static void wakeup() {
synchronized (thread) {
thread.notify();
}
}
public static void shutdown() {
synchronized (thread) {
service.running = false;
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("shutdown");
}
public static void main(String[] args) throws IOException {
SomeService.wakeup();
System.in.read();
SomeService.wakeup();
System.in.read();
SomeService.shutdown();
}
}
I'm concerned that the variables should be declared volatile. And also concerned that I should check in the "what needs to be done part" for thread.isInterrupted(). Does this seem like the right approach? Should I translate this to executors? How can I force a run on a scheduled executor?
EDIT
After experimenting with the executor, it seems that this approach seems reasonable. What do you think?
public class SomeExecutorService implements Runnable {
private static final SomeExecutorService runner
= new SomeExecutorService();
private static final ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();
// properties
ScheduledFuture<?> scheduled = null;
// constructors
private SomeExecutorService() {
}
// methods
public void schedule(int seconds) {
scheduled = executor.schedule(runner, seconds, TimeUnit.SECONDS);
}
public void force() {
if (scheduled.cancel(false)) {
schedule(0);
}
}
public void run() {
try {
_logger.trace("doing what is needed");
} catch (Exception e) {
_logger.error("unexpected exception", e);
} finally {
schedule(DELAY_SECONDS);
}
}
// static methods
public static void initialize() {
runner.schedule(0);
}
public static void wakeup() {
runner.force();
}
public static void destroy() {
executor.shutdownNow();
}
}
For starters - you probably don't want to implement Runnable yourself; you should take in a Runnable. You should only implement Runnable if you expect your class to be passed to others to execute.
Why not just wrap a ScheduledExecutorService? Here's a quick (very poor, but ought to be functional) implementation.
public class PokeableService {
private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
private final Runnable codeToRun;
public PokeableService (Runnable toRun, long delay, long interval, TimeUnit units) {
codeToRun = toRun;
service.scheduleAtFixedRate(toRun, delay, interval, units);
}
public void poke () {
service.execute(codeToRun);
}
}
The variables do not need to be volatile since they are read and modified in a synchronized block.
You should use a different object for the lock then the thread, since the Thread class does it's own synchronization.
I would recommend using a single threaded ScheduledExecutorService and remove sleeping. Then if you want to run the task during the current sleep period, you can submit it to the executor again for a single time run. Just use the execute or submit methods in ExecutorService which ScheduledExecutorService extends.
About checking for isInterrupted, you should do this if the do work portion can take a lot of time, can be cancelled in the middle, and is not calling methods that block and will throw an interrupted exception any ways.
Using wait/notify should be a more efficient method. I also agree with the suggestion that using 'volatile' is not necessary and synchronizing on an alternative object would be wise to avoid conflicts.
A few other suggestions:
Start the thread elsewhere, starting from a static block is not good practice
Putting the execute logic in an "execute()" method or similar would be desirable
This code implements the above suggestions. Note also that there is only the one thread performing the SomeService execution logic and that it will occur INTERVAL milliseconds after the time it last completed. You should not get duplicate executions after a manually triggered wakeUp() call.
public class SomeService implements Runnable {
private static final INTERVAL = 15 * 1000;
private Object svcSynchronizer = new Object();
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
try {
svcSynchronizer.wait(INTERVAL);
} catch (InterruptedException e) {
// ignore interruptions
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void wakeUp() {
svcSynchronizer.notifyAll();
}
public void shutdown() {
running = false;
svcSynchronizer.notifyAll();
}
}

Categories

Resources