I have two threads running concurrently, a main thread and a listener that implements Runnable.
The main thread and listener each have a critical section, specifically the method getObjectList(String) in the Manager class that runs in the main thread and handleNewObjects(String, List<Object>) that runs in the listener thread.
My current plan is to make getObjectList() a synchronized method:
class Manager {
protected synchronized getObjectList() {
// Do critical section stuff
}
}
and make handleNewObjects() look like this
class Listener implements Runnable {
private final Manager myManager;
handleNewObjects() {
synchronized (myManager) {
// Do critical section stuff
}
}
}
Will this ensure my critical sections never run simultaneously?
Should I synchronize some other way?
If getObjectList() was to be a synchronized method, and myManager in Listener was the same Manager instance as the instance that will modify a shared set of objects, then yes it would work.
It is hard to say without knowing the relationships between your existing code to know if there's a better solution for you, however this approach could be seen as somewhat fragile. A change to what object Manager locks on would cause Listener to not be thread-safe anymore, and if the shared objects the two critical sections modify already exist in Manager, you might as well have Listener call another synchronized in Manager, say myManager.handleNewObjects().
What I mean by a change to what object Manager locks on is if Manager went from:
protected synchronized getObjectList() {
// Do critical section stuff
}
to
protected getObjectList() {
synchronized (myPrivateFinalLockObject) {
// Do critical section stuff
}
}
or
protected getObjectList() {
delegatingWorkToSomeOtherThreadSafeObject.getObjectList();
}
Then Listener isn't thread-safe anymore as it doesn't lock it's critical section on the same object anymore.
Will this ensure my critical sections never run simultaneously?
Yes, but as Quirliom noted, be sure they are the same object. If you're using any frameworks, beware of framework created proxies.
Should I synchronize some other way?
Producer-consumer setups are pretty common. Things get trickier when you have multiples of each. Rather than reinvent it yourself, you can take a look at some classes that are built into the platform. From the Javadocs (not exactly what you're doing, but close):
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
Assuming that getObjectsList is a retrieval method with no updates, you could improve on concurrency utilizing ReadWriteLocks. Here the handle* method is the method that updates the underlying list. Please see:
http://ilkinbalkanay.blogspot.com/2008/01/readwritelock-example-in-java.html
Related
I need to know, if there is some framework which could provide me this funcionality. I have one critical section in one method and I need few other methods wait until this critical section is executed and finished. If critical section is not active, those methods should fluently work.
And if critical section is entered only when no thread is in semaphored methods.
Such as:
public class Worker {
private Critical critical = null;
private CriticalDependent dep1 = null;
private CriticalDependent dep2 = null;
public Worker() {
critical = new Critical();
dep1 = critical.registerDependent();
dep2 = critical.registerDependent();
}
public void critical() {
critical.enter();
critical.waitForClearToGo();
// protected unique code
// change resource handle etc
critical.exit();
}
public void dependent1() {
critical.checkWaitAndUnsetClearToGo(this.dep1);
// some dependent code
// use resource handle
critical.setClearToGo(this.dep1);
}
public void dependent2() {
critical.checkWaitAndUnsetClearToGo(this.dep2);
// some dependent code
// use resource handle
critical.setClearToGo(this.dep2);
}
}
I can figure out some solution, but I prefer to use existing framework. And I cannot find existing one. Thank you in advance.
Use the standard Java Semaphore.
You can do this with Java's Semaphore as already told by Erik.
However you need one with 2 permits, so that your 2 dependent methods can run at the same time, but the critical section will block both of the dependent methods.
Semaphore semaphore = new Semaphore(2, true); // Make it fair, so critical section won't wait unnecessarily
public void critical() {
semaphore.acquire(2); // Blocks both dependents, waiting if they're not available
...
semaphore.release(2);
}
public void dep1() {
semaphore.acquire(); // Blocks only if critical() has both permits
...
semaphore.release();
}
public void dep2() {
semaphore.acquire(); // Ditto, dep1() can have the other permit
...
semaphore.release();
}
I've got the following code:
while(!currentBoard.boardIsValid()){
for (QueueLocation location : QueueLocation.values()){
while(!inbox.isEmpty(location)){
Cell c = inbox.dequeue(location);
notifyNeighbours(c.x, c.y, c.getCurrentState(),previousBoard);
}
}
}
I've got a consumer with a few queues (all of their methods are synchronised). One queue for each producer. The consumer loops over all the queues and checks if they've got a task for him to consume.
If the queue he's checking has a task in it, he consumes it. Otherwise, he goes to the check the next queue until he finishes iterating over all the queues.
As of now, if he iterates over all the queues and they're all empty, he keeps on looping rather than waiting for one of them to contain something (as seen by the outer while).
How can I make the consumer wait until one of the queues has something in it?
I'm having an issue with the following scenario: Lets say there are only 2 queues. The consumer checked the first one and it was empty. Just as he's checking the second one (which is also empty), the producer put something in the first queue. As far as the consumer is concerned, the queues are both empty and so he should wait (even though one of them isn't empty anymore and he should continue looping).
Edit:
One last thing. This is an exercise for me. I'm trying to implement the synchronisation myself. So if any of the java libraries have a solution that implements this I'm not interested in it. I'm trying to understand how I can implement this.
#Abe was close. I would use signal and wait - use the Object class built-ins as they are the lightest weight.
Object sync = new Object(); // Can use an existing object if there's an appropriate one
// On submit to queue
synchronized ( sync ) {
queue.add(...); // Must be inside to avoid a race condition
sync.notifyAll();
}
// On check for work in queue
synchronized ( sync ) {
item = null;
while ( item == null ) {
// Need to check all of the queues - if there will be a large number, this will be slow,
// and slow critical sections (synchronized blocks) are very bad for performance
item = getNextQueueItem();
if ( item == null ) {
sync.wait();
}
}
}
Note that sync.wait releases the lock on sync until the notify - and the lock on sync is required to successfully call the wait method (it's a reminder to the programmer that some type of critical section is really needed for this to work reliably).
By the way, I would recommend a queue dedicated to the consumer (or group of consumers) rather than a queue dedicated to the producer, if feasible. It will simplify the solution.
If you want to block across multiple queues, then one option is to use java's Lock and Condition objects and then use the signal method.
So whenever the producer has data, it should invoke the signallAll.
Lock fileLock = new ReentrantLock();
Condition condition = fileLock.newCondition();
...
// producer has to signal
condition.signalAll();
...
// consumer has to await.
condition.await();
This way only when the signal is provided will the consumer go and check the queues.
I solved a similar situation along the lines of what #Abe suggests, but settled on using a Semaphore in combination with an AtomicBoolean and called it a BinarySemaphore. It does require the producers to be modified so that they signal when there is something to do.
Below the code for the BinarySemaphore and a general idea of what the consumer work-loop should look like:
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class MultipleProdOneConsumer {
BinarySemaphore workAvailable = new BinarySemaphore();
class Consumer {
volatile boolean stop;
void loop() {
while (!stop) {
doWork();
if (!workAvailable.tryAcquire()) {
// waiting for work
try {
workAvailable.acquire();
} catch (InterruptedException e) {
if (!stop) {
// log error
}
}
}
}
}
void doWork() {}
void stopWork() {
stop = true;
workAvailable.release();
}
}
class Producer {
/* Must be called after work is added to the queue/made available. */
void signalSomethingToDo() {
workAvailable.release();
}
}
class BinarySemaphore {
private final AtomicBoolean havePermit = new AtomicBoolean();
private final Semaphore sync;
public BinarySemaphore() {
this(false);
}
public BinarySemaphore(boolean fair) {
sync = new Semaphore(0, fair);
}
public boolean release() {
boolean released = havePermit.compareAndSet(false, true);
if (released) {
sync.release();
}
return released;
}
public boolean tryAcquire() {
boolean acquired = sync.tryAcquire();
if (acquired) {
havePermit.set(false);
}
return acquired;
}
public boolean tryAcquire(long timeout, TimeUnit tunit) throws InterruptedException {
boolean acquired = sync.tryAcquire(timeout, tunit);
if (acquired) {
havePermit.set(false);
}
return acquired;
}
public void acquire() throws InterruptedException {
sync.acquire();
havePermit.set(false);
}
public void acquireUninterruptibly() {
sync.acquireUninterruptibly();
havePermit.set(false);
}
}
}
I need advice on the following:
I have a #Scheduled service method which has a fixedDelay of a couple of seconds in which it does scanning of a work queue and processing of apropriate work if it finds any. In the same service I have a method which puts work in the work queue and I would like this method to imediately trigger scanning of the queue after it's done (since I'm sure that there will now be some work to do for the scanner) in order to avoid the delay befor the scheduled kicks in (since this can be seconds, and time is somewhat critical).
An "trigger now" feature of the Task Execution and Scheaduling subsystem would be ideal, one that would also reset the fixedDelay after execution was initiated maually (since I dont want my manual execution to collide with the scheduled one). Note: work in the queue can come from external source, thus the requirement to do periodic scanning.
Any advice is welcome
Edit:
The queue is stored in a document-based db so local queue-based solutions are not appropriate.
A solution I am not quite happy with (don't really like the usage of raw threads) would go something like this:
#Service
public class MyProcessingService implements ProcessingService {
Thread worker;
#PostCreate
public void init() {
worker = new Thread() {
boolean ready = false;
private boolean sleep() {
synchronized(this) {
if (ready) {
ready = false;
} else {
try {
wait(2000);
} catch(InterruptedException) {
return false;
}
}
}
return true;
}
public void tickle() {
synchronized(this) {
ready = true;
notify();
}
}
public void run() {
while(!interrupted()) {
if(!sleep()) continue;
scan();
}
}
}
worker.start();
}
#PreDestroy
public void uninit() {
worker.interrup();
}
public void addWork(Work work) {
db.store(work);
worker.tickle();
}
public void scan() {
List<Work> work = db.getMyWork();
for (Work w : work) {
process();
}
}
public void process(Work work) {
// work processing here
}
}
Since the #Scheduled method wouldn't have any work to do if there are no items in the work-queue, that is, if no one put any work in the queue between the execution cycles. On the same note, if some work-item was inserted into the work-queue (by an external source probably) immediately after the scheduled-execution was complete, the work won't be attended to until the next execution.
In this scenario, what you need is a consumer-producer queue. A queue in which one or more producers put in work-items and a consumer takes items off the queue and processes them. What you want here is a BlockingQueue. They can be used for solving the consumer-producer problem in a thread-safe manner.
You can have one Runnable that performs the tasks performed by your current #Scheduled method.
public class SomeClass {
private final BlockingQueue<Work> workQueue = new LinkedBlockingQueue<Work>();
public BlockingQueue<Work> getWorkQueue() {
return workQueue;
}
private final class WorkExecutor implements Runnable {
#Override
public void run() {
while (true) {
try {
// The call to take() retrieves and removes the head of this
// queue,
// waiting if necessary until an element becomes available.
Work work = workQueue.take();
// do processing
} catch (InterruptedException e) {
continue;
}
}
}
}
// The work-producer may be anything, even a #Scheduled method
#Scheduled
public void createWork() {
Work work = new Work();
workQueue.offer(work);
}
}
And some other Runnable or another class might put in items as following:
public class WorkCreator {
#Autowired
private SomeClass workerClass;
#Override
public void run() {
// produce work
Work work = new Work();
workerClass.getWorkQueue().offer(work);
}
}
I guess that's the right way to solve the problem you have at hand. There are several variations/configurations that you can have, just look at the java.util.concurrent package.
Update after question edited
Even if the external source is a db, it is still a producer-consumer problem. You can probably call the scan() method whenever you store data in the db, and the scan() method can put the data retrieved from the db into the BlockingQueue.
To address the actual thing about resetting the fixedDelay
That is not actually possible, wither with Java, or with Spring, unless you handle the scheduling part yourself. There is no trigger-now functionality as well. If you have access to the Runnable that's doing the task, you can probably call the run() method yourself. But that would be the same as calling the processing method yourself from anywhere and you don't really need the Runnable.
Another possible workaround
private Lock queueLock = new ReentrantLock();
#Scheduled
public void findNewWorkAndProcess() {
if(!queueLock.tryLock()) {
return;
}
try {
doWork();
} finally {
queueLock.unlock();
}
}
void doWork() {
List<Work> work = getWorkFromDb();
// process work
}
// To be called when new data is inserted into the db.
public void newDataInserted() {
queueLock.lock();
try {
doWork();
} finally {
queueLock.unlock();
}
}
the newDataInserted() is called when you insert any new data. If the scheduled execution is in progress, it will wait until it is finished and then do the work. The call to lock() here is blocking since we know that there is some work in the database and the scheduled-call might have been called before the work was inserted. The call to acquire lock in findNewWorkAndProcess() in non-blocking as, if the lock has been acquired by the newDataInserted method, it would mean that the scheduled method shouldn't be executed.
Well, you can fine tune as you like.
Is it possible to write Thread creation listener in java? For example using aop?!
I mean something like this that if my application creates a thread I would like to register this object in my own table, container or something.
I would create a thread that continously lists all running threads on the JVM.
Then each time it noticies that a new thread has appeared, it would notify in either way a class in your code.
Here are some links about how to list all threads currently running on the JVM :
Get a List of all Threads currently running in Java
Listing All Running Threads
============
A starting code :
ThreadCreationListener.java
public interface ThreadCreationListener {
public void onThreadCreation(Thread newThread);
}
ThreadCreationMonitor.java
public class ThreadCreationMonitor extends Thread {
private List<ThreadCreationListener> listeners;
private boolean canGo;
public ThreadCreationMonitor() {
listeners = new Vector<ThreadCreationListener>();//Vector class is used because many threads may use a ThreadCreationMonitor instance.
canGo = true;
// Initialize the rest of the class here...
}
// Most important methods
public void addListener(ThreadCreationListener tcl) {
listeners.add(tcl);
}
public void removeListener(ThreadCreationListener tcl) {
listeners.remove(tcl);
}
public void run() {
List<Thread> runningThreads;
List<Thread> lastRunningThreads = new ArrayList<>();
while(canGo) {
// Step 1 - List all running threads (see previous links)
// runningThreads = ...
// Step 2 - Check for new threads and notify all listeners if necessary
if (runningThreads.removeAll(lastRunningThreads)==true) {
for(Thread t : runningThreads) {
for(ThreadCreationListener tcl : listeners) {
lastRunningThreads.add(t);
tcl.onThreadCreation(t); //Notify listener
}
}
}
}
}
public void shutdown() {
canGo = false;
}
}
MyThreadInfoConsumer.java
public class MyThreadInfoConsumer implements ThreadCreationListener {
public void onThreadCreation(Thread newThread) {
// Process here the notification...
}
}
Main.java
public class Main {
public static void main(String[] args) {
ThreadCreationMonitor tcm = new ThreadCreationMonitor();
tcm.start();
MyThreadInfoConsumer myTIC = new MyThreadInfoConsumer();
tcm.addListener(myTIC);
// rest of your code...
// Don't forget to call tcm.shutdown() when exiting your application !
}
}
I think this would be possible with AOP (aspectj for instance). But it is still required to create your own Thread and ThreadGroup/Executor types, unless you can recompile the JDK classes with the aspect compiler. Define the pointcut on your thread's start method if you want to register on thread launching or on the createThread of your pool if you want to register on the creation of the thread objects.
The following works only if you recompiled the JDK with the aspect compiler:
All threads are started with Thread.start, so write a pointcut for that method then you can use advices to do what you'd like to. Of course this is not perfect since e.g. a cachedThreadPool executor might not start a new thread for each task, but maybe if you register a pointcut on Runnable.run and Callable.call rather than on Thread.start, that might be sufficient enough.
Perhaps a ThreadGroup is what you need. All Threads are members of a ThreadGroup and when you start a new Thread it is added to the same group as its parent by default.
In theory its possible (but not recommended) to sub-class to be notified when a Thread is added or removed from the group.
It is likely that polling the threads of this groups, or polling all threads is a better solution.
In the Observer Design Pattern, the subject notifies all observers by calling the update() operation of each observer. One way of doing this is
void notify() {
for (observer: observers) {
observer.update(this);
}
}
But the problem here is each observer is updated in a sequence and update operation for an observer might not be called till all the observers before it is updated. If there is an observer that has an infinite loop for update then all the observer after it will never be notified.
Question:
Is there a way to get around this problem?
If so what would be a good example?
The problem is the infinite loop, not the one-after-the-other notifications.
If you wanted things to update concurrently, you'd need to fire things off on different threads - in which case, each listener would need to synchronize with the others in order to access the object that fired the event.
Complaining about one infinite loop stopping other updates from happening is like complaining that taking a lock and then going into an infinite loop stops others from accessing the locked object - the problem is the infinite loop, not the lock manager.
Classic design patterns do not involve parallelism and threading. You'd have to spawn N threads for the N observers. Be careful though since their interaction to this will have to be done in a thread safe manner.
You could make use of the java.utils.concurrent.Executors.newFixedThreadPool(int nThreads) method, then call the invokeAll method (could make use of the one with the timout too to avoid the infinite loop).
You would change your loop to add a class that is Callable that takes the "observer" and the "this" and then call the update method in the "call" method.
Take a look at this package for more info.
This is a quick and dirty implementation of what I was talking about:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Main
{
private Main()
{
}
public static void main(final String[] argv)
{
final Watched watched;
final List<Watcher> watchers;
watched = new Watched();
watchers = makeWatchers(watched, 10);
watched.notifyWatchers(9);
}
private static List<Watcher> makeWatchers(final Watched watched,
final int count)
{
final List<Watcher> watchers;
watchers = new ArrayList<Watcher>(count);
for(int i = 0; i < count; i++)
{
final Watcher watcher;
watcher = new Watcher(i + 1);
watched.addWatcher(watcher);
watchers.add(watcher);
}
return (watchers);
}
}
class Watched
{
private final List<Watcher> watchers;
{
watchers = new ArrayList<Watcher>();
}
public void addWatcher(final Watcher watcher)
{
watchers.add(watcher);
}
public void notifyWatchers(final int seconds)
{
final List<Watcher> currentWatchers;
final List<WatcherCallable> callables;
final ExecutorService service;
currentWatchers = new CopyOnWriteArrayList<Watcher>(watchers);
callables = new ArrayList<WatcherCallable>(currentWatchers.size());
for(final Watcher watcher : currentWatchers)
{
final WatcherCallable callable;
callable = new WatcherCallable(watcher);
callables.add(callable);
}
service = Executors.newFixedThreadPool(callables.size());
try
{
final boolean value;
service.invokeAll(callables, seconds, TimeUnit.SECONDS);
value = service.awaitTermination(seconds, TimeUnit.SECONDS);
System.out.println("done: " + value);
}
catch (InterruptedException ex)
{
}
service.shutdown();
System.out.println("leaving");
}
private class WatcherCallable
implements Callable<Void>
{
private final Watcher watcher;
WatcherCallable(final Watcher w)
{
watcher = w;
}
public Void call()
{
watcher.update(Watched.this);
return (null);
}
}
}
class Watcher
{
private final int value;
Watcher(final int val)
{
value = val;
}
public void update(final Watched watched)
{
try
{
Thread.sleep(value * 1000);
}
catch (InterruptedException ex)
{
System.out.println(value + "interupted");
}
System.out.println(value + " done");
}
}
I'd be more concerned about the observer throwing an exception than about it looping indefinitely. Your current implementation would not notify the remaining observers in such an event.
1. Is there a way to get around this problem?
Yes, make sure the observer work fine and return in a timely fashion.
2. Can someone please explain it with an example.
Sure:
class ObserverImpl implements Observer {
public void update( Object state ) {
// remove the infinite loop.
//while( true ) {
// doSomething();
//}
// and use some kind of control:
int iterationControl = 100;
int currentIteration = 0;
while( curentIteration++ < iterationControl ) {
doSomething();
}
}
private void doSomething(){}
}
This one prevent from a given loop to go infinite ( if it makes sense, it should run at most 100 times )
Other mechanism is to start the new task in a second thread, but if it goes into an infinite loop it will eventually consume all the system memory:
class ObserverImpl implements Observer {
public void update( Object state ) {
new Thread( new Runnable(){
public void run() {
while( true ) {
doSomething();
}
}
}).start();
}
private void doSomething(){}
}
That will make the that observer instance to return immediately, but it will be only an illusion, what you have to actually do is to avoid the infinite loop.
Finally, if your observers work fine but you just want to notify them all sooner, you can take a look at this related question: Invoke a code after all mouse event listeners are executed..
All observers get notified, that's all the guarantee you get.
If you want to implement some fancy ordering, you can do that:
Connect just a single Observer;
have this primary Observer notify his friends in an order you define in code or by some other means.
That takes you away from the classic Observer pattern in that your listeners are hardwired, but if it's what you need... do it!
If you have an observer with an "infinite loop", it's no longer really the observer pattern.
You could fire a different thread to each observer, but the observers MUST be prohibited from changing the state on the observed object.
The simplest (and stupidest) method would simply be to take your example and make it threaded.
void notify() {
for (observer: observers) {
new Thread(){
public static void run() {
observer.update(this);
}
}.start();
}
}
(this was coded by hand, is untested and probably has a bug or five--and it's a bad idea anyway)
The problem with this is that it will make your machine chunky since it has to allocate a bunch of new threads at once.
So to fix the problem with all the treads starting at once, use a ThreadPoolExecutor because it will A) recycle threads, and B) can limit the max number of threads running.
This is not deterministic in your case of "Loop forever" since each forever loop will permanently eat one of the threads from your pool.
Your best bet is to not allow them to loop forever, or if they must, have them create their own thread.
If you have to support classes that can't change, but you can identify which will run quickly and which will run "Forever" (in computer terms I think that equates to more than a second or two) then you COULD use a loop like this:
void notify() {
for (observer: observers) {
if(willUpdateQuickly(observer))
observer.update(this);
else
new Thread(){
public static void run() {
observer.update(this);
}
}.start();
}
}
Hey, if it actually "Loops forever", will it consume a thread for every notification? It really sounds like you may have to spend some more time on your design.