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();
}
Related
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
I am developing an application which performs allows the user to adjust several parameters and then performs a computation which can take up to a minute, after which it displays the result to the user.
I would like the user to be able to adjust the parameters and restart the calculation, terminating the progress of the current calculation.
Additionally, from the programming perspective, I would like to be able to block until the calculation is completed or interrupted, and be able to know which.
In pseudo code, this is roughly what I am looking for:
method performCalculation:
interrupt current calculation if necessary
asynchronously perform calculation with current parameters
method performCalculationBlock:
interrupt current calculation if necessary
perform calculation with current parameters
if calculation completes:
return true
if calculation is interrupted:
return false
What I have so far satisfies the first method, but I am not sure how to modify it to add the blocking functionality:
private Thread computationThread;
private Object computationLock = new Object();
private boolean pendingComputation = false;
...
public MyClass() {
...
computationThread = new Thread() {
public void run() {
while (true) {
synchronized (computationLock) {
try {
computationLock.wait();
pendingComputation = false;
calculate();
} catch (InterruptedException e) {
}
}
}
}
private void checkForPending() throws InterruptedException {
if (pendingComputation)
throw new InterruptedException();
}
private void calculate() {
...
checkForPending();
...
checkForPending();
...
// etc.
}
};
computationThread.start();
}
private void requestComputation() {
pendingComputation = true;
synchronized (computationLock) {
computationLock.notify();
}
}
What is the best way to go about adding this functionality? Or is there a better way to design the program to accomplish all of these things?
If you are using JDK 5 or earlier, check the java.util.concurrent package. The FutureTask class seems to match your requirement: a cancellable asynchronous computation with blocking feature.
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.
I have a method, say method1(), that takes a while to run. During it's execution, if there is another call to method1(), it should be ignored. I have, roughly, something like this
boolean mFlag = false;
void method1()
{
if(!mFlag)
{
mFlag=true;
// do Stuff
mFlag=false;
}
}
This works. But I was wondering if there is a better way to do this preferably not involving any flags.
Yes, you should really be using something from java.util.concurrent.locks Your example isn't quite strictly correct, that boolean needs to be volatile.
ReentrantLock lock = new ReentrantLock();
void method1()
{
if(lock.tryLock())
{
try {
if (!(lock.getHoldCount() > 1)) {
//do Some Stuff
}
} finally {
lock.unlock();
}
}
}
Edited to handle skipping execution on reentrance as inidicated in your comment. Unfortunatly there isn't really a great way to do that with the built in library, as it's a bit of an odd usecase, but I still think using the built in library is a better option.
Are you trying to guard against re-entry from the same thread or multiple threads accessing at the same time.
Assuming multi-threaded access, the light approach is to use java.util.concurrent.atomic. No need for anything as "heavy" as a lock (provided there are not further requirements).
Assuming no-reentry from the same method:
private final AtomicBoolean inMethod = new AtomicBoolean();
void method1() {
if (inMethod.compareAndSet(true, false)) { // Alternatively getAndSet
try {
// do Stuff
} finally {
inMethod.set(false); // Need to cover exception case!
}
}
}
If you want to allow reentry within the same thread, then it gets messy enough to use locks:
private final AtomicReference<Thread> inMethod = new AtomicReference<Thread>();
void method1() {
final Thread current = Thread.currentThread();
final Thread old = inMethod.get();
if (
old == current || // We already have it.
inMethod.compareAndSet(null, current) // Acquired it.
) {
try {
// do Stuff
} finally {
inMethod.set(old); // Could optimise for no change.
}
}
}
Could use the Execute Around idiom for this.
Maybe you should use synchronized methods
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html