Java is semaphore priority

I have several threads accessing an external resource - the browser. But only one thread can access it at a time. So, I use a semaphore to synchronize them. However, one thread that takes input from the GUI and then accesses the browser for results should take precedence over other threads, and I'm not sure how to use the semaphore to achieve it.

I thought that each thread after receiving the semaphore checks if there is a priority queue in the queue, and if so, it frees it and waits again. Only the priority thread does not release it after receiving it.

Is this a good solution or is there something else in the Java API that I could use?

+8
java multithreading semaphore
source share
3 answers

Here is a simple, no-frills answer. This is similar to how a read / write lock works, except that each locker has exclusive access (usually all readers go in parallel). Note that he does not use Semaphore , because this is almost always the wrong design.

 public class PrioLock { private boolean _locked; private boolean _priorityWaiting; public synchronized void lock() throws InterruptedException { while(_locked || _priorityWaiting) { wait(); } _locked = true; } public synchronized void lockPriority() throws InterruptedException { _priorityWaiting = true; try { while(_locked) { wait(); } _locked = true; } finally { _priorityWaiting = false; } } public synchronized void unlock() { _locked = false; notifyAll(); } } 

You would use it as one of the Lock types in java.util.concurrent:

Common topics:

 _prioLock.lock(); try { // ... use resource here ... } finally { _prioLock.unlock(); } 

"A priority":

 _prioLock.lockPriority(); try { // ... use resource here ... } finally { _prioLock.unlock(); } 

UPDATE:

Response to comment regarding “proactive” thread interactions:

In a general sense, you cannot do this. you could create custom functionality that added “pause points” to the locked section that would allow a low priority stream to get a high priority stream, but this would be fraught with danger.

The only thing you could really do is to interrupt the workflow by forcing it to exit the blocked code block (provided that your working code responds to the interrupt). This would allow the high priority thread to accelerate due to the loss of the downstream of the downstream (and you might also need to implement rollback logic).

to implement this you need:

  • write "current thread" when the lock succeeds.
  • in lockPriority() , abort the "current thread" if it is found.
  • implement logic between calls to lock() / unlock() (low priority) to:
    • It responds to interruption in a reasonable amount of time.
    • it implements any necessary "rollback" code upon interruption
  • potentially implement the retry logic outside of lock() / unlock() calls (low priority) to re-execute any work lost during interruption
+2
source share

There are no synchronization primitives in Java that allow you to prioritize one thread over others the way you want.

But you could use a different approach to solving your problem. Instead of synchronizing threads, they create small tasks (e.g. Runnable objects) and put these tasks in a PriorityBlockingQueue with tasks from the highest priority GUI thread. One workflow will check tasks from this queue and execute them. This guarantees both mutual exclusion and prioritization.

ThreadPoolExecutor has special constructors that accept blocking queues. So, all you need is a one-thread performer that comes with your PriorityBlockingQueue<Runnable> . Then send your assignments to this performer, and he will take care of the rest.

If you decide to choose this approach, this post may interest you: How to implement PriorityBlockingQueue using ThreadPoolExecutor and custom tasks

+6
source share

You are mixing concepts here.

Semaphores are just one of many options for "synchronizing" thread streams. They have nothing for thread prioritization and thread scheduling.

Thread priorities, on the other hand, are a topic on their own. You have tools in Java to influence them; but the results of such actions are largely dependent on the underlying platform / OS; and the JVM implementation itself. Theoretically, using these priorities is easy , but as said; reality is more complex .

In other words: you can only use your semaphore to ensure that only one thread is using your queue at a time. This in no way helps to ensure that your GUI read thread will outperform other threads when CPU cycles become a problem. But if you're lucky, the answer to your problem will be a simple call to setPriority () ; using different priorities.

0
source share

All Articles