Is there a way to enforce only a single execution of a thread object?
Something like a thread singleton?
To illustrate, consider below example:
I have a runnable implemented class.
I would like that I will be able to call start() method only one time of the object.
You can put a boolean as attribute to check if the thread has already been launch
Add a static boolean field in your Runnable and check it at the start of the run method like this:
synchronized(MyRunnable.class) {
if(alreadyRan) {
return;
}
alreadyRan = true;
}
Well, with the tips of my friends here in this thread, I reached the following:
public class TestThread extends Thread {
static private TestThread _instance = null;
private TestThread() {}
public static TestThread getThread(){
if(_instance == null)
_instance = new TestThread();
return _instance;
}
#Override
public void run()
{
System.out.println("Hello");
}
}
And this is an example of using it, when calling start for the second time throws an exception:
public class Main {
public static void main(String[] args) {
try {
TestThread.getThread().start();
TestThread.getThread().start();
} catch (IllegalThreadStateException e) {
System.out.println("Error: Tried to start more than one instance of this thread!");
e.printStackTrace();
}
}
}
Your comments are welcomed.
Related
class PublishService {
public void longRunningPublish() {
...
}
}
From different places in code, the method can be invoked.
caller1.longRunningPublish();
caller2.longRunningPublish();
...
callerN.longRunningPublish();
Question: how can I prevent longRunningPublish running concurrently? Each invocation should stack and be delay, and only start when the previous run has finished.
Could I do better than the following?
class PublishService {
private boolean running;
public void throttleLongRunningPublish() {
while (running) {
TimeUnit.SECONDS.sleep(10);
}
running = true;
try {
longRunningPublish();
} finally {
running = false;
}
}
}
Your code is not thread safe.
If you create multiple instances of PublishService and run them concurrently the boolean variable has no effect.
If your instance of PublishService is a singleton and the same class is executed by different threads there there is no guarantee that the method will be executed serially because multiple thread could enter the method before reaching the instruction:
running = true;
This is a simple example than handles serialization if there are multiple instances of the same class along with a "demo" main
public class PublishService {
private static final Logger logger= LoggerFactory.getLogger(PublishService.class.getName());
private static final Lock lock=new ReentrantLock();
public void longRunningPublish() {
lock.lock();
try {
logger.info("{} longRunningPublish before sleep",Thread.currentThread().getId());
Thread.sleep(500);
logger.info("{} longRunningPublish after sleep",Thread.currentThread().getId());
} catch (InterruptedException e) {
logger.error(e.getMessage(),e);
} finally {
lock.unlock();
}
}
public static void main(String args[]) {
ExecutorService executor=Executors.newFixedThreadPool(10);
for(int i=0;i<20;i++) {
executor.submit(() -> {
PublishService publishService = new PublishService();
publishService.longRunningPublish();
});
}
}
}
If the class is a singleton you can remove the static qualifier of the lock variable.
In order to prevent concurrent access, you need to lock the resource while it is being used with something like a ReentrantLock. If you need to guarantee in-order access, you can use the constructor ReentrantLock(boolean fair) with fair set to true. Otherwise, you can use a basic ReentractLock or the synchronized property.
I found a neat way with Semaphore:
class PublishService {
private static final Semaphore lock = new Semaphore(1);
public void throttleLongRunningPublish() {
try {
lock.tryAcquire(2, TimeUnit.MINUTES);
longRunningPublish();
} finally {
lock.release();
}
}
}
This question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
Was trying to practice producer and consumer using a simple counter in java.
Not sure why I am getting a Illegal Monitor State exception on this piece of code.
I have counter rest and counter consume methods which run in their own thread.
The counter itself is a static int volatile field .
The counter class also gives you a lock to
If I change the wait naotify to the following:
Counter.lock.notify();
Counter.lock.wait();
The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?
Producer Class
package multithreading;
public class CounterProducer implements Runnable {
public void run() {
try { incrCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void incrCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter < 1) {
System.out.println("Counter Reset");
Counter.counter = 10;
notify();
wait();
}
}
}
}
}
Consumer Class
package multithreading;
public class CounterConsumer implements Runnable {
public void run() {
try { consumeCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void consumeCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter > 0) {
System.out.println("Consumed");
Counter.counter--;
notify();
wait();
}
}
}
}
}
The Counter
public class Counter {
public static volatile int counter;
public static final Object lock = new Object();
}
The Counter
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
The Runner
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
If I change the wait naotify to the following, the code works:
Counter.lock.notify();
Counter.lock.wait();
Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.
That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().
this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.
This question already has answers here:
Program hangs if thread is created in static initializer block
(4 answers)
Closed 6 years ago.
This class does not initialize itself in the usual way, so it calls on the help of background thread.
From my understanding ,surely the program must print true ?
But If you ran the program, you found that it prints nothing; it just hangs.
public class Test {
private static boolean isInitialized = false;
static {
Thread t = new Thread(new Runnable() {
public void run() {
isInitialized = true;
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
System.out.println(isInitialized);
}
}
Can some one please explain why this is happening.
"The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field." Static Initialization Blocks
I guess that this program to start needs to first initialize the class Test. And so it tries first to execute static block but that block never exits (since it cannot set static member isInitialized as it is not ready yet).
So Test class is never fully initialized and therefore main method is not even starting to be executed.
The solution for you could be moving the instruction of waiting for your initialization thread to finish - to the main method. So it does not block the Test class from being fully initailzed.
package com.company;
public class Test {
private static boolean isInitialized = false;
static Thread t = new Thread(new Runnable() {
public void run() {
isInitialized = true;
}
});
static {
t.start();
}
public static void main(String[] args) {
try {
t.join();
} catch (InterruptedException ignored) { }
System.out.println(isInitialized);
}
}
I have a main class which spawns a thread, let's call them MainClass and MyThread.
public class MainClass extends javax.swing.JFrame {
int sharedVariable;
MyThread threadInstance;
public MainClass (){
sharedVariable = 2;
threadInstance = new MyThread(this);
threadInstance.run();
}
public int getSharedVariable(){ return sharedVariable; }
public static void main(String[] args){
//begin main class
}
}
public class MyThread implements Runnable {
MainClass class;
public MyThread(MainClass main_class){
this.main_class= main_class;
}
#Override
public run(){
while(this.main_class is still active){
//grab status of sharedVariable and wait for x amount of time.
}
}
}
The problem is I do not know how to implement the while condition which checks if the MainClass instance is still alive and if it is, it has to use the this.main_class.getSharedVariable() to get the value of sharedVariable, then wait for x amount of time. MainClass has the main method .
I would recommend holding onto the Thread instance and then calling threadInstance.interrupt() right before the main(...) method exits.
Something like:
public static void main(String[] args){
MainClass mainClass = new MainClass();
try {
...
// do main stuff here
...
} finally {
mainClass.threadInstance.interrupt();
}
}
Then in your thread you'd do:
while(!Thread.currentThread().isInterrupted()){
...
}
You'd also want to handle InterruptedException correctly:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// always a good pattern to re-interrupt the thread here
Thread.currentThread().interrupt();
// if we are interrupted quit
return;
}
Btw, it is very bad form to leak the instance of an object during construction to another thread:
new MyThread(this);
See here: Why shouldn't I use Thread.start() in the constructor of my class?
Also, you aren't starting a thread when you call threadInstance.run();. You are just running it in the current thread. You should use threadInstance.start() but not inside of the constructor like that.
You can use CountDownLatch which is very convenient for such tasks as waiting other threads to finish some activity (you can change Thread.sleep(...) argument in main to, say, 12000L and see what happens):
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
class OtherThread extends Thread {
private final CountDownLatch sharedLatch;
OtherThread(CountDownLatch sharedLatch) {
this.sharedLatch = sharedLatch;
}
#Override
public void run() {
boolean wokenByMain = false;
try {
wokenByMain = sharedLatch.await(10000L, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
return; // or not return, whatever makes more sense in your case
}
System.out.println("heh: " + wokenByMain);
}
}
class SOSample {
public static void main(String[] args) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(1);
OtherThread otherThread = new OtherThread(latch);
otherThread.start();
System.out.println("Scheduled other thread to be started");
Thread.sleep(1000L);
System.out.println("going to release other thread");
latch.countDown();
}
}
public class MainClass extends JFrame implements Runnable {
public static void main(String [] args) {
final Thread t=new Thread(new MainClass() {
public void run(){
//something
});
Thread t2=new Thread(new MyThread() {
public void run() {
while(t.isAlive) {
//something
}
}
});
}
}
I have some code that I want to have some one time initialisation performed. But this code doesn't have a definite lifecycle, so my logic can be potentially invoked by multiple threads before my initialisation is done. So, I want to basically ensure that my logic code "waits" until initialisation is done.
This is my first cut.
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
synchronized(initialised) {
initStuff();
initialised.getAndSet(true);
initialised.notifyAll();
}
}
public void doStuff() {
synchronized(initialised) {
if (!initialised.get()) {
try {
initialised.wait();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
}
}
doOtherStuff();
}
}
I basically want to make sure this is going to do what I think it's going to do -- block doStuff until the initialised is true, and that I'm not missing a race condition where doStuff might get stuck on a Object.wait() that will never arrive.
Edit:
I have no control over the threads. And I want to be able to control when all of the initialisation is done, which is why doStuff() can't call initialise().
I used an AtomicBoolean as it was a combination of a value holder, and an object I could synchronize. I could have also simply had a "public static final Object lock = new Object();" and a simple boolean flag. AtomicBoolean conveniently gave me both. A Boolean can not be modified.
The CountDownLatch is exactly what I was looking for. I also considered using a Sempahore with 0 permits. But the CountDownLatch is perfect for just this task.
That's a strange mix of library and built-in concurrency controls. Something like this is much cleaner:
public class MyClass {
private static final CountDownLatch latch = new CountDownLatch(1);
public void initialise() {
initStuff();
latch.countDown();
}
public void doStuff() {
try {
latch.await();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
doOtherStuff();
}
}
A synchronized block will automatically block other threads. Just use a simple lock object + status variable:
public class MyClass {
private static boolean initialised;
private static final Object lockObject = new Object();
public void initialise() {
synchronized (lockObject) {
if (!initialised) {
initStuff();
initialised = true;
}
}
}
public void doStuff() {
initialise();
doOtherStuff();
}
}
The best may be to use a static initializer (as mentioned by SB):
public class MyClass {
public static void doInitialize() {
...
}
public void doStuff() {
doOtherStuff();
}
static {
doInitialize();
}
}
This will get executed once before any other code is allowed to be called. If you will always have to initialize anytime the class is used then there is no performance hit as the class will not be loaded until it is used. See the answers to this question for more details.
It this is right at startup, why not wait to start the other threads until the initialization is complete?
Also, you can do a thread-synchronized IsComplete boolean that is set to false until it is set to true by the initialization routine.
You're using AtomicBoolean always from inside a synchronized block. There's not much point to that since only one thread can access it. Atomic variables are intended for use in lock-free solutions - you can get and set the value as an uninterruptable unit.
I guess you are looking for a lock free solution once the intiialization has happened:
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
if (!intialized.get())
{
synchornized (this)
{
if (!initialized.getAndSet(true))
doInitialize();
}
}
}
public void doStuff() {
initialize();
doOtherStuff();
}
You could also do this with a simple volatile boolean which is actually a little more efficient than an AtomicBoolean.