why IdleConnectionMonitorThread need to synchronize - java

I see many examples of IdleConnectionMonitorThread using 'synchronized' in implement of 'run'. In my mind, it makes no sense.
The implement in
edu.uci.ics
crawler4j
4.2
public class IdleConnectionMonitorThread extends Thread {
private final PoolingHttpClientConnectionManager connMgr;
private volatile boolean shutdown;
public IdleConnectionMonitorThread(PoolingHttpClientConnectionManager connMgr) {
super("Connection Manager");
this.connMgr = connMgr;
}
#Override
public void run() {
try {
while (!shutdown) {
synchronized (this) {
wait(5000);
// Close expired connections
connMgr.closeExpiredConnections();
// Optionally, close connections that have been idle longer than 30 sec
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
}
} catch (InterruptedException ignored) {
// terminate
}
}
public void shutdown() {
shutdown = true;
synchronized (this) {
notifyAll();
}
log.warn("newPosition: shutdown idleMonitorThread");
}
}
Since in most cases we only have one IdleConnectionMonitorThread and use it in this way, synchronized (this) has no meaning.
IdleConnectionMonitorThread idleConnectionMonitorThread = new IdleConnectionMonitorThread(poolingHttpClientConnectionManager)
I wonder the benefit of using 'synchronized', can use implement run in this way (delete the synchronized)
#Override
public void run() {
try {
while (!shutdown) {
wait(5000);
// Close expired connections
connMgr.closeExpiredConnections();
// Optionally, close connections that have been idle longer than 30 sec
connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
}
} catch (InterruptedException ignored) {
// terminate
}
}

Read the javadocs for Object.wait(long).
If you call it when you don't hold the mutex you are waiting on, you will get an exception. The javadoc states:
Throws: IllegalMonitorStateException - if the current thread is not the owner of the object's monitor.
In general, locking the mutex in the "wait/notify" protocol is essential to ensure that the shared state that is being managed is visible to all threads that are participating. In this case the shutdown variable is declared as volatile so that isn't a concern. However, the "wait/notify" protocol requires locking anyway; see above.
I wonder the benefit of using synchronized, can use implement run in this way (delete the synchronized).
Nope. If you deleted the synchronized you would get an exception. But you could replace Object.wait(...) with Thread.sleep(...) ... and then the synchronized would be unnecessary.
As to the "oddness" of this code, who knows why the author ended up with this. But does it really matter? There is an Engineering principle: "If it ain't broken, don't fix it". Nobody has proposed a reason why this code is broken.

Related

The run method of Java thread does not take the updated status

The code below is my run method. This stat status does not take the newly updated status from my stop method.
#Override
public void run() {
synchronized (this) {
while (!stat) {
try {
this.wait();
} catch (InterruptedException ex) {
Logger.getLogger(TrafficLightSimulator.class.getName()).log(Level.SEVERE, null, ex);
} }
}
}
In the above code, the program does not enter while loop. It is because the stat boolean new changed value from the stop method is not taken in run method.
This is my new stop
public void stop() {
synchronized(this) {
this.stopStat = false;
this.notifyAll();
}
}
I even defined the stat as the volatile boolean variable. However, this also does not seem to work.
While you have the "waiting" part correct, your "setting" part is missing some important parts.
The first part that is missing is the lock:
public void stop() {
synchronized(this) {
this.stat = true;
}
}
This lock makes sure that only 1 thread can change/access it at the same time, as is required by the Java memory model. Without this lock (and without volatile), Java makes no guarantee that changes to this variable are seen by other threads.
The next part that missing is the notifying part, it is important to "wake" up all waiting threads when the condition is changed:
public void stop() {
synchronized(this) {
this.stat = true;
this.notifyAll();
}
}
The last part of your error happens due the fact you are setting the variable to true, while for the code to be inside the while loop, the variable is already true. You probably want to set it to false instead
public void stop() {
synchronized(this) {
this.stat = false;
this.notifyAll();
}
}
Memory visibility isn't an issue here because both the code reading the flag and the code setting the flag are synchronized, holding the same lock. If your code won't enter the while loop it must be that some other thread has the lock.
This is another reason (in addition to the reasons below) to use interrupt instead of wait/notify for this. Interruption doesn't depend on acquiring a lock to work.
Use interrupt for this instead. There's no good reason for your own flag here when one is provided for you, using wait/notify for this is unnecessary and can cause problems since you may need to wait/notify for other reasons.
The Java api docs advise against locking on threads, by the way. That's what join does. Implicit locking doesn't have a way to have different conditions get separate notifications for a lock (the way ReentrantLock does).
For a thread that does things with intermittent sleeps in between, the run method can look like:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
doStuff();
Thread.sleep(1000L);
} catch (InterruptedException e) {
// no need to log this as an error, it's not an error
Thread.currentThread().interrupt();
}
}
}
Real world code uses threadpools where you submit Runnable or Callable tasks, the java.util.concurrent classes expect your code to handle interruption.

Understanding wait() and notify() methods

I'm trying to understand how Java's wait and notify methods work. As per the documentation, wait() causes thread to wait for subsequent calls to notify() or notifyAll() methods but for some reason notify doesn't interrupt "waiting":
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
});
thread1.start();
// unblock thread1 in 2 seconds
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (thread1) {
thread1.notify();
}
}
You need to notify the object that is being waited on, not the thread that is waiting.
In your case the object waited on is an instance of an anonymous inner class, which is problematic because you cannot easily obtain a reference to it in order to notify it. You could solve this by extending Thread directly:
Thread thread1 = new Thread() {
#Override
public void run() {
System.out.println("thread1 is started, waiting for notify()");
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
System.out.println("waiting is over");
}
};
Now the this (in synchronized (this)) refers to the thread itself, and the wait is called on the thread object too. In this case your current call to notify should be fine, since it notifies the same object (which happens in this case to be the thread that is waiting - but just to be clear, that need not be the case).
It isn't considered good practice to use an object for synchronisation that may also be used elsewhere; instances of Thread would be an example of this, and in fact the documentation specifically advises against it:
It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Also, you should correctly handle spurious wakeup; that is, wait may return because notify/notifyAll was called elsewhere or perhaps was not even called at all. As the documentation also says:
A thread can also wake up without being notified, interrupted, or timing out, a so-called spurious wakeup. While this will rarely occur in practice, applications must guard against it by testing for the condition that should have caused the thread to be awakened, and continuing to wait if the condition is not satisfied. In other words, waits should always occur in loops [...]
Therefore, your example should really use a separate variable to track whether the wakeup was intentional (due to an explicit notify) or not.
for some reason notify doesn't interrupt "waiting":
#davmac's answer is correct but for posterity, there are some other ways you can do it because extending Thread and calling wait() and notify() on the Thread object is not recommended.
The best way would be to create a lock object. Making your lock objects final is always a good pattern although here it is also necessary to use it in the inner class.
final Object lock = new Object();
Thread thread1 = new Thread(new Runnable() {
...
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
// always a good pattern
Thread.currentThread().interrupt();
System.out.println(e.getLocalizedMessage());
}
}
...
}
...
synchronized (lock) {
lock.notify();
}
// might as well wait for it to finish
thread1.join();

Thread methods deprecated [duplicate]

How do you kill a java.lang.Thread in Java?
See this thread by Sun on why they deprecated Thread.stop(). It goes into detail about why this was a bad method and what should be done to safely stop threads in general.
The way they recommend is to use a shared variable as a flag which asks the background thread to stop. This variable can then be set by a different object requesting the thread terminate.
Generally you don't..
You ask it to interrupt whatever it is doing using Thread.interrupt() (javadoc link)
A good explanation of why is in the javadoc here (java technote link)
In Java threads are not killed, but the stopping of a thread is done in a cooperative way. The thread is asked to terminate and the thread can then shutdown gracefully.
Often a volatile boolean field is used which the thread periodically checks and terminates when it is set to the corresponding value.
I would not use a boolean to check whether the thread should terminate. If you use volatile as a field modifier, this will work reliable, but if your code becomes more complex, for instead uses other blocking methods inside the while loop, it might happen, that your code will not terminate at all or at least takes longer as you might want.
Certain blocking library methods support interruption.
Every thread has already a boolean flag interrupted status and you should make use of it. It can be implemented like this:
public void run() {
try {
while (!interrupted()) {
// ...
}
} catch (InterruptedException consumed)
/* Allow thread to exit */
}
}
public void cancel() { interrupt(); }
Source code adapted from Java Concurrency in Practice. Since the cancel() method is public you can let another thread invoke this method as you wanted.
One way is by setting a class variable and using it as a sentinel.
Class Outer {
public static volatile flag = true;
Outer() {
new Test().start();
}
class Test extends Thread {
public void run() {
while (Outer.flag) {
//do stuff here
}
}
}
}
Set an external class variable, i.e. flag = true in the above example. Set it to false to 'kill' the thread.
I want to add several observations, based on the comments that have accumulated.
Thread.stop() will stop a thread if the security manager allows it.
Thread.stop() is dangerous. Having said that, if you are working in a JEE environment and you have no control over the code being called, it may be necessary; see Why is Thread.stop deprecated?
You should never stop stop a container worker thread. If you want to run code that tends to hang, (carefully) start a new daemon thread and monitor it, killing if necessary.
stop() creates a new ThreadDeathError error on the calling thread and then throws that error on the target thread. Therefore, the stack trace is generally worthless.
In JRE 6, stop() checks with the security manager and then calls stop1() that calls stop0(). stop0() is native code.
As of Java 13 Thread.stop() has not been removed (yet), but Thread.stop(Throwable) was removed in Java 11. (mailing list, JDK-8204243)
There is a way how you can do it. But if you had to use it, either you are a bad programmer or you are using a code written by bad programmers. So, you should think about stopping being a bad programmer or stopping using this bad code.
This solution is only for situations when THERE IS NO OTHER WAY.
Thread f = <A thread to be stopped>
Method m = Thread.class.getDeclaredMethod( "stop0" , new Class[]{Object.class} );
m.setAccessible( true );
m.invoke( f , new ThreadDeath() );
I'd vote for Thread.stop().
As for instance you have a long lasting operation (like a network request).
Supposedly you are waiting for a response, but it can take time and the user navigated to other UI.
This waiting thread is now a) useless b) potential problem because when he will get result, it's completely useless and he will trigger callbacks that can lead to number of errors.
All of that and he can do response processing that could be CPU intense. And you, as a developer, cannot even stop it, because you can't throw if (Thread.currentThread().isInterrupted()) lines in all code.
So the inability to forcefully stop a thread it weird.
The question is rather vague. If you meant “how do I write a program so that a thread stops running when I want it to”, then various other responses should be helpful. But if you meant “I have an emergency with a server I cannot restart right now and I just need a particular thread to die, come what may”, then you need an intervention tool to match monitoring tools like jstack.
For this purpose I created jkillthread. See its instructions for usage.
There is of course the case where you are running some kind of not-completely-trusted code. (I personally have this by allowing uploaded scripts to execute in my Java environment. Yes, there are security alarm bell ringing everywhere, but it's part of the application.) In this unfortunate instance you first of all are merely being hopeful by asking script writers to respect some kind of boolean run/don't-run signal. Your only decent fail safe is to call the stop method on the thread if, say, it runs longer than some timeout.
But, this is just "decent", and not absolute, because the code could catch the ThreadDeath error (or whatever exception you explicitly throw), and not rethrow it like a gentlemanly thread is supposed to do. So, the bottom line is AFAIA there is no absolute fail safe.
'Killing a thread' is not the right phrase to use. Here is one way we can implement graceful completion/exit of the thread on will:
Runnable which I used:
class TaskThread implements Runnable {
boolean shouldStop;
public TaskThread(boolean shouldStop) {
this.shouldStop = shouldStop;
}
#Override
public void run() {
System.out.println("Thread has started");
while (!shouldStop) {
// do something
}
System.out.println("Thread has ended");
}
public void stop() {
shouldStop = true;
}
}
The triggering class:
public class ThreadStop {
public static void main(String[] args) {
System.out.println("Start");
// Start the thread
TaskThread task = new TaskThread(false);
Thread t = new Thread(task);
t.start();
// Stop the thread
task.stop();
System.out.println("End");
}
}
There is no way to gracefully kill a thread.
You can try to interrupt the thread, one commons strategy is to use a poison pill to message the thread to stop itself
public class CancelSupport {
public static class CommandExecutor implements Runnable {
private BlockingQueue<String> queue;
public static final String POISON_PILL = “stopnow”;
public CommandExecutor(BlockingQueue<String> queue) {
this.queue=queue;
}
#Override
public void run() {
boolean stop=false;
while(!stop) {
try {
String command=queue.take();
if(POISON_PILL.equals(command)) {
stop=true;
} else {
// do command
System.out.println(command);
}
} catch (InterruptedException e) {
stop=true;
}
}
System.out.println(“Stopping execution”);
}
}
}
BlockingQueue<String> queue=new LinkedBlockingQueue<String>();
Thread t=new Thread(new CommandExecutor(queue));
queue.put(“hello”);
queue.put(“world”);
t.start();
Thread.sleep(1000);
queue.put(“stopnow”);
http://anandsekar.github.io/cancel-support-for-threads/
Generally you don't kill, stop, or interrupt a thread (or check wheter it is interrupted()), but let it terminate naturally.
It is simple. You can use any loop together with (volatile) boolean variable inside run() method to control thread's activity. You can also return from active thread to the main thread to stop it.
This way you gracefully kill a thread :) .
Attempts of abrupt thread termination are well-known bad programming practice and evidence of poor application design. All threads in the multithreaded application explicitly and implicitly share the same process state and forced to cooperate with each other to keep it consistent, otherwise your application will be prone to the bugs which will be really hard to diagnose. So, it is a responsibility of developer to provide an assurance of such consistency via careful and clear application design.
There are two main right solutions for the controlled threads terminations:
Use of the shared volatile flag
Use of the pair of Thread.interrupt() and Thread.interrupted() methods.
Good and detailed explanation of the issues related to the abrupt threads termination as well as examples of wrong and right solutions for the controlled threads termination can be found here:
https://www.securecoding.cert.org/confluence/display/java/THI05-J.+Do+not+use+Thread.stop%28%29+to+terminate+threads
Here are a couple of good reads on the subject:
What Do You Do With InterruptedException?
Shutting down threads cleanly
I didn't get the interrupt to work in Android, so I used this method, works perfectly:
boolean shouldCheckUpdates = true;
private void startupCheckForUpdatesEveryFewSeconds() {
Thread t = new Thread(new CheckUpdates());
t.start();
}
private class CheckUpdates implements Runnable{
public void run() {
while (shouldCheckUpdates){
//Thread sleep 3 seconds
System.out.println("Do your thing here");
}
}
}
public void stop(){
shouldCheckUpdates = false;
}
Thread.stop is deprecated so how do we stop a thread in java ?
Always use interrupt method and future to request cancellation
When the task responds to interrupt signal, for example, blocking queue take method.
Callable < String > callable = new Callable < String > () {
#Override
public String call() throws Exception {
String result = "";
try {
//assume below take method is blocked as no work is produced.
result = queue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return result;
}
};
Future future = executor.submit(callable);
try {
String result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
logger.error("Thread timedout!");
return "";
} finally {
//this will call interrupt on queue which will abort the operation.
//if it completes before time out, it has no side effects
future.cancel(true);
}
When the task does not respond to interrupt signal.Suppose the task performs socket I/O which does not respond to interrupt signal and thus using above approach will not abort the task, future would time out but the cancel in finally block will have no effect, thread will keep on listening to socket. We can close the socket or call close method on connection if implemented by pool.
public interface CustomCallable < T > extends Callable < T > {
void cancel();
RunnableFuture < T > newTask();
}
public class CustomExecutorPool extends ThreadPoolExecutor {
protected < T > RunnableFuture < T > newTaskFor(Callable < T > callable) {
if (callable instanceof CancellableTask)
return ((CancellableTask < T > ) callable).newTask();
else
return super.newTaskFor(callable);
}
}
public abstract class UnblockingIOTask < T > implements CustomCallable < T > {
public synchronized void cancel() {
try {
obj.close();
} catch (IOException e) {
logger.error("io exception", e);
}
}
public RunnableFuture < T > newTask() {
return new FutureTask < T > (this) {
public boolean cancel(boolean mayInterruptIfRunning) {
try {
this.cancel();
} finally {
return super.cancel(mayInterruptIfRunning);
}
}
};
}
}
After 15+ years of developing in Java there is one thing I want to say to the world.
Deprecating Thread.stop() and all the holy battle against its use is just another bad habit or design flaw unfortunately became a reality... (eg. want to talk about the Serializable interface?)
The battle is focusing on the fact that killing a thread can leave an object into an inconsistent state. And so? Welcome to multithread programming. You are a programmer, and you need to know what you are doing, and yes.. killing a thread can leave an object in inconsistent state. If you are worried about it use a flag and let the thread quit gracefully; but there are TONS of times where there is no reason to be worried.
But no.. if you type thread.stop() you're likely to be killed by all the people who looks/comments/uses your code. So you have to use a flag, call interrupt(), place if(!flag) all around your code because you're not looping at all, and finally pray that the 3rd-party library you're using to do your external call is written correctly and doesn't handle the InterruptException improperly.

Executor shutdownNow with blocked tasks?

I am using Executors for thread pool, and submitting tasks. Can executorService.shutdownNow will shutdown all the tasks even though some of them may be blocked on I/O calls to database or Socket?
It depends on whether your tasks are well written!
The documentation says: "The shutdown() method will allow previously submitted tasks to execute before terminating, while the shutdownNow() method prevents waiting tasks from starting and attempts to stop currently executing tasks."
However, Java doesn't kill threads "out of thin air". It tries to interrupt them. A good task will throw an InterruptException of some sort when shtudownNow tries to interrupt them, and end gracefully. You mention socket communication- most decent clients' blocking methods will throw an interrupted exception if they are interrupted.
An example of a bad task might be (rather obviously) to run a thread with while(true) { readChunk(); if(endOfChunks) { break;} }. This offers no graceful interrupt check! It's the old rule not to use while loops to wait, but to wait() using syncronized on a 'blocker' object that can be interrupted.
No, there is no guarantee. If you see the API doc for ExecutorService#shutdownNow. It says,
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks.
If you want to block until all tasks have completed execution after a shutdown request,use ExecutorService#awaitTermination.
When its not possible to handle interrupts (java.io), non-standard shutdown logic is required.
My solution to encapsulating this problem combines the examples 'TrackingExecutorService' and 'SocketUsingTask' from 'Java Concurrency In Practice'.
Define a 'Shutdownable' interface
Extend ThreadPoolExecutor to track running submitted tasks that implement the 'Shutdownable' interface
override ThreadPoolExecutor's shutdownNow to invoke non-standard shutdown logic via the 'Shutdownable' interface
public interface Shutdownable {
public void shutdown();
}
public class ShutdowningExecutor extends ThreadPoolExecutor{
private final Set runningShutdownables
= Collections.synchronizedSet(new HashSet());
#Override
protected RunnableFuture newTaskFor(final Callable callable){
if (callable instanceof Shutdownable) {
runningShutdownables.add((Shutdownable) callable);
return super.newTaskFor(new Callable(){
#Override
public T call() throws Exception {
T t = callable.call();
runningShutdownables.remove((Shutdownable) callable);
return t;
}
});
} else
return super.newTaskFor(callable);
}
public void shutdownAll() {
for(Shutdownable shutdownable : runningShutdownables) {
shutdownable.shutdown();
}
}
#Override
public List shutdownNow(){
shutdownAll();
return super.shutdownNow();
}
}
public abstract class ShutdownableViaCloseable implements Shutdownable{
private Closeable closeable;
protected synchronized void setCloseable(Closeable c) { closeable = c; }
public synchronized void shutdown() {
try {
if (closeable != null)
closeable.close();
} catch (IOException ignored) { }
}
}
public class MySocketTask extends ShutdownableViaCloseable implements Callable {
public MySocketTask(Socket s) {
setCloseable(s);
//constructor stuff
}
public Void call() {
try (Socket socket = this.socket) {
while(!socket.isClosed) {
//do stuff
}
}
}
}
Simply put: you cannot rely on that. The ExecutorService simply interrupts the running tasks; it is up to the implementation of the tasks if they really cancel their endeavor. Some I/O can (and will) be interrupted, especially the java.nio stuff, but the java.io is most likely not interrupted. See What does java.lang.Thread.interrupt() do? for a bit more explanation.

Synchronized functions in Java

I have a class with a function which is synchronized like so:
public synchronized void enqueue(int number) {...}
In my program I have several threads running all wanting to use this function on a specific object of the class. What I would like to happen is for the threads to simply try using the function and if it is locked to not wait on it simply skip running that function.
Can this be done without using the Java.util.concurency library and only using syncronization primatives?
The restriction of not using concurrency is not optional
I like the AtomicInteger solution, but of course AtomicInteger is part of the concurrency package. You can follow the same principle (with lower efficiency, though) with the following simple code:
private boolean locked = false;
public void enqueue(int number) {
synchronized (this) {
if (locked) {
return;
}
locked = true;
}
try {
// Synchronized goodness goes here.
} finally {
synchronized (this) {
locked = false;
}
}
}
Since you're restricted here, here's what I would do:
Make a class with the ability to tell it that you want to lock on it. There are two types of locks: passive lock, and active lock. A passive lock will allow an unlimited number of threads to pass. An active lock will make it belong only to that thread.
When you want a passive lock, you have to register yourself, and unregister yourself when you're done. You'll wait on an internal object until all active locks are done.
When you want an active lock, you wait for all current passive locks have unregistered. If there's currently an active lock (store a thread reference to see if there is, utilizing Thread.currentThread()) then wait until notified. You can then set yourself as the referred thread. When you unregister, if there are waiting active locks, notify one of them (consider a Set<Thread> to register this). If there aren't, notify all the passive locks that are waiting and they can go through.
There's going to be a lot of unanswered questions here, and I doubt it's perfect, but this is most of what you're looking for...
Rather than use any synchronization primitives I'd recommend using something like the AtomicInteger class to leverage a CAS (compare-and-swap) operation for your anti-concurrency strategy:
public void enqueue(int number) {
if (!atomicInteger.compareAndSet(0, 1) {
return;
}
try {
// Synchronized goodness goes here.
} finally {
atomicInteger.set(0);
}
}
May be you can you synchronize the object that handles the Queue. If someone else ois using the queue the enqueue does nothing. I have an example that compiles and run. Very simple example but not pretty:
class Queue {
public void enqueue(int number) {
// something in this method for demo purposes only
try {
Thread.sleep(100);
} catch (InterruptedException e){}
System.out.println(Thread.currentThread().getName()+" done");
}
}
class Demo {
private static Queue e = new Queue();
public void enqueue(int number) {
Queue q = getQueue();
if (q!=null) {
q.enqueue(number);
releaseQueue(q);
} else {
// do nothing since the queue is being used
System.out.println(Thread.currentThread().getName()+" done doing nothing");
}
}
public synchronized Queue getQueue() {
Queue b = e;
e = null;
return b;
}
public synchronized void releaseQueue(Queue q) {
e = q;
}
public static void main(String[] args) {
for (int j = 0; j < 5; j++) {
Thread t = new Thread(new Runnable() {
public void run() {
Demo d = new Demo();
d.enqueue(5);
}
}, "Thread "+j);
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException e){}
}
}
}
YES You can implement locking on your own by managing a static variable in that class, or a using a "lock" text file, for example.
HOWEVER Although this simplistic hack would not be terribly difficult --- the java.util.concurrency package solution would be EVEN EASIER, AND is a better choice because, as you will quickly find, when building multithreaded resources into applications our needs will quickly exceed your current expectations
Don't worry about the WHOLE concurrency package -- I find that just taking 3 minutes to learn how to use the AtomicBoolean or AtomicLong fields can be enough to enable simple, multithreaded logic with a minimal effort.

Categories

Resources