Synchronizing infinitely looped service's initialization part - java

I'm trying to implement a piece of code to synchronously start looped service in Java. The idea is, code under // STARTER comment should be considered as piece of Service.go() method, so if service fails to start, I want to re-throw the exception synchronously. That piece of code should only finish in case I've tried to start the thread, waited until its execution flow reached some point and next, if there are no problems, my go() method quits and thread goes on, or, if there were problems, I can re-throw the exception caught in thread's run() method from my go() method. Here's the solution that seems to work fine, but I'm curious if it's possible to make it a couple times shorter :-)
public class Program {
private static boolean started;
private static Throwable throwable;
public static void main(String[] args) {
final Object startedSetterLock = new Object();
Thread thread = new Thread() {
public void run() {
System.out.printf("trying to start...\n");
boolean ok;
Throwable t = null;
try {
init();
ok = true;
} catch(Exception e) {
ok = false;
t = e;
}
synchronized(startedSetterLock) {
started = ok;
throwable = t;
startedSetterLock.notifyAll();
}
if(!ok) {
return;
}
while(true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
private void init() throws Exception { throw new Exception(); } // may throw
};
// STARTER
synchronized(startedSetterLock) {
thread.start();
try {
startedSetterLock.wait();
} catch(InterruptedException e) {
System.out.printf("interrupted\n");
}
}
// here I'm 100% sure that service has either started or failed to start
System.out.printf("service started: %b\n", started);
if(!started) {
throwable.printStackTrace();
}
}
}
And also, there's a reason to have initialization code executed within that thread, so, please, don't advise running initialization code explicitly in go() method and then just passing all the stuff to the thread.
Thanks!

How about overriding the Thread.start() method?
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while (true) {
try {
System.out.printf("working...\n");
Thread.sleep(1000);
} catch (InterruptedException e) {
System.out.printf("interrupted\n");
}
}
}
#Override
public synchronized void start() {
try {
init();
} catch (Exception e) {
throw new RuntimeException(e);
}
super.start();
}
private void init() throws Exception {
throw new Exception("test");
}
};
t.start();
}

Related

Can static variables ever be used to synchronize threads?

Below I have constructed an example which synchronizes three threads based on a static variable:
public class CallMethodsInOrder {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
Thread first = new Thread(new FooRunner(new Foo(),MethodToCall.FIRST));
Thread second = new Thread(new FooRunner(new Foo(),MethodToCall.SECOND));
Thread third = new Thread(new FooRunner(new Foo(),MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo {
static boolean hasFirstRun = false;
static boolean hasSecondRun = false;
static boolean hasThirdRun = false;
public Foo() {
}
public void first() {
System.out.println("First");
hasFirstRun = true;
}
public void second() {
System.out.println("Second");
hasSecondRun = true;
}
public void third() {
System.out.println("Third");
hasThirdRun = true;
}
}
class FooRunner implements Runnable{
private Foo foo;
private MethodToCall method;
public FooRunner(Foo foo, MethodToCall method) {
this.foo = foo;
this.method = method;
}
#Override
public void run() {
if(method == MethodToCall.FIRST) {
foo.first();
}
else if (method == MethodToCall.SECOND){
while(!Foo.hasFirstRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.second();
}
else if (method == MethodToCall.THIRD) {
while(!Foo.hasSecondRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.third();
}
}
}
enum MethodToCall{
FIRST, SECOND, THIRD;
}
Is this a valid approach? I have read that static variables are not thread safe, however, cannot see a situation in which the above code would not execute the three methods in the desired order (first, second, third).
Many answers I have found have been related to accessing data structures with multiple threads vs ordering of methods as displayed here.
Since each static variable is only being modified by a single thread is it a problem?
As suggested in the comments, using synchronized is likely the way forward here. I feel the above code still works with static variables however is definitely not the best practise.
A related solution including Semaphores is included below:
public class CallMethodsInOrder2 {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
// This approach uses Semaphore vs static variables.
Foo2 foo2 = new Foo2();
Thread first = new Thread(new FooRunner2(foo2,MethodToCall.FIRST));
Thread second = new Thread(new FooRunner2(foo2,MethodToCall.SECOND));
Thread third = new Thread(new FooRunner2(foo2,MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo2 {
private Semaphore one, two;
public Foo2() {
one = new Semaphore(1);
two = new Semaphore(1);
try {
one.acquire();
two.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void first() {
System.out.println("First");
one.release();
}
public void second() {
try {
one.acquire();
System.out.println("Second");
one.release();
two.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void third() {
try {
two.acquire();
two.release();
System.out.println("Third");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I think the static variable method 'works' in this case (for some value of 'works'), but is definitely less efficient.
You're sleeping an arbitrary amount of time in each thread ('100'), and then waking up to poll this variable. In the case of a semaphore, the OS takes care of the sleep/wake events to the threads.

Given the below code about Deadlock...why deadlock is not happening here and what changes should i make to occur the deadlock

public class Test15_DeadLockUsingJoinMethod {
public static void main(String[] args) throws InterruptedException {
JoinThread1 jt1=new JoinThread1(jt2);
JoinThread2 jt2=new JoinThread2(jt1);
jt1.start();
jt2.start();
}
}
class JoinThread1 extends Thread {
JoinThread2 jt2;
public JoinThread1(JoinThread2 jt2) {
this.jt2=jt2;
}
public void run() {
System.out.println("1st thread execution start");
try {
jt2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1st thread execution stopped");
}
}
class JoinThread2 extends Thread {
JoinThread1 jt1;
public JoinThread2(JoinThread1 jt1) {
this.jt1=jt1;
}
public void run() {
System.out.println("2nd thread execution start");
try {
jt1.join();
} catch (InterruptedException e){
e.printStackTrace();
}
System.out.println("2nd thread execution stopped");
}
}
Here I want to see the deadlock condition using only join() method. I know the deadlock code using synchronized keyword. But how can we execute deadlock condition using join method?
Your code doesn´t compile, you are using jt2 in the constructor of jt1, before it is defined.
In order to get a deadlock, you should define a new constructor for JoinThread1 that do not have any parameter. So, you first define jt1 using the new constructor. Then you define jt2 passing through parameter jt1 (like you have now). Then you should define a setter for the other thread in JoinThread1.
Example:
New constructor
public JoinThread1() {
}
Setter method
public void setThread(JoinThread2 jt2){
this.jt2 = jt2;
}
Main
public static void main(String[] args) throws InterruptedException {
JoinThread1 jt1=new JoinThread1();
JoinThread2 jt2=new JoinThread2(jt1);
jt1.setThread(jt2);
jt1.start();
jt2.start();
}
After that changes,you will get a deadlock.

handle java exception in Thread.run

I have an inner class that extends Thread
private class TestStart extends Thread {
public void run() {
try {
startServer();
}
catch (Exception e) {
/// How to handle it?
}
}
}
The caller in the main thread:
public void start() throws Exception {
Thread st = new TestStart();
st.start();
}
Method startServer() throws Exception by its API, so I have to use try-catch as Thread.run() does not "throws" exception in method definition. I need to bubble up the caught exception into the main thread to handle it. Is there an easy way to do it? Thanks
If you use an ExecutorService instead of using raw threads, you can be notified of uncaught exceptions:
class MyCallable implements Callable<Void> {
#Override public Void call() throws Exception {
// Do something - you don't need to catch Exception as Callable throws it.
// ...
return null; // A return is necessary from a Callable.
}
}
Create an executor service somewhere, e.g.:
ExecutorService executor = Executors.newFixedThreadPool(1);
Then, in the code where you start the thread:
Future<?> future = executor.submit(new MyCallable());
try {
future.get(); // Blocks until the Callable completes.
} catch (ExecutionException e) {
// You reach here if an exception is thrown in the Callable -
// The exception is accessible via e.getCause().
}
Set a new exception handler on your Thread.
st.setDefaultUncaughtExceptionHandler(new Thread.
UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(t + " throws exception: " + e);
}
});
And place that code before your start();
There is a few possible solutions. For example:
Use setUncaughtExceptionHandler()/setDefaultUncaughtExceptionHandler() and change your try/catch
try {
startServer();
}
catch (RuntimeException e) {
throw e;
}
catch (Exception e) {
throw new RuntimeException(e);
}
Or use your custom listener
private class TestStart extends Thread {
private final ServerStateListener lnr;
TestStart(ServerStateListener lnr) {
this.lnr = lnr;
}
public void run() {
try {
startServer();
lnr.onServerStarted();
}
catch (Exception e) {
lnr.onServerStoppedByError(e);
}
}
}
Or just save Exception and read it after .join
private class TestStart extends Thread {
private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication
public void run() {
try {
startServer();
}
catch (Exception e) {
error = e;
}
}
public Exception getError() {
return error;
}
}
Or use ExecutorService/Callable instead of your own thread as Andy suggested.

Print odd and even using two threads in Java

I am trying to do it using two threads like below. Can someone point the obvious mistake I am doing here?
public class OddEven {
public static boolean available = false;
public static Queue<Integer> queue = new LinkedList<Integer>();
static Thread threadEven = new Thread() {
#Override
public void run() {
printEven();
}
public synchronized void printEven() {
while (!available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = false;
notifyAll();
}
};
static Thread threadOdd = new Thread() {
#Override
public void run() {
printOdd();
}
public synchronized void printOdd () {
while (available) {
try {
wait();
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
System.out.println(queue.remove());
available = true;
notifyAll();
}
};
public static void main(String[] args) {
int n = 20;
for (int i = 1; i < n; i++) {
queue.add(i);
}
threadOdd.start();
threadEven.start();
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
threadOdd.join();
threadEven.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
But this program is only printing 1 and quitting. After printing 1 the available should be true and printEven should wake up, print and set available to false. I don't understand what is going wrong here? I saw other solutions but want to know why my solution is not working.
Putting synchronized on an instance method means that the thread calling that method has to acquire the lock on that instance; public void synchronized printOdd() is syntax sugar for
public void printOdd() {
synchronized(this) {
...
}
}
where this is different for each instance, since ThreadOdd and threadEven are two different objects and each one uses its own lock. The methods notifyAll and wait are called on the object that is being used as the lock. When one thread waits it never gets notified because the notification only applies to other threads waiting on the same lock as the notifying thread.

Time out method in java

In a java class I have a method that sometimes takes a long time for execution. Maybe it hangs in that method flow. What I want is if the method doesn't complete in specific time, the program should exit from that method and continue with the rest of flow.
Please let me know is there any way to handle this situation.
You must use threads in order to achieve this. Threads are not harmful :) Example below run a piece of code for 10 seconds and then ends it.
public class Test {
public static void main(String args[])
throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("0");
method();
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + 10000;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
System.out.println("1");
break;
}
try {
System.out.println("2");
Thread.sleep(500);
}
catch (InterruptedException t) {}
}
}
static void method() {
long endTimeMillis = System.currentTimeMillis() + 10000;
while (true) {
// method logic
System.out.println("3");
if (System.currentTimeMillis() > endTimeMillis) {
// do some clean-up
System.out.println("4");
return;
}
}
}
}
Execute the method in a different thread, you can end a thread at anytime.
Based on the above snipplet, I tried creating a glorified spring bean.
Such executor runs the passed limitedRuntimeTask in limited runtimeInMs.
If the task finishes within its time limits, the caller continues normally in execution.
If the limitedRuntimeTask fails to finish in the defined runtimeInMs,
the caller will receive the thread execution back. If a timeBreachedTask was defined,
it will be executed before returning to caller.
public class LimitedRuntimeExecutorImpl {
public void runTaskInLessThanGivenMs(int runtimeInMs, final Callable limitedRuntimeTask, final Callable timeBreachedTask) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
LOGGER.info("Started limitedRuntimeTask");
limitedRuntimeTask.call();
LOGGER.info("Finished limitedRuntimeTask in time");
} catch (Exception e) {
LOGGER.error("LimitedRuntimeTask exception", e);
}
}
});
thread.start();
long endTimeMillis = System.currentTimeMillis() + runtimeInMs;
while (thread.isAlive()) {
if (System.currentTimeMillis() > endTimeMillis) {
LOGGER.warn("LmitedRuntimeTask did not finish in time (" + runtimeInMs + ")ms. It will run in vain.");
if(timeBreachedTask != null ){
try {
LOGGER.info("Executing timeBreachedTask");
timeBreachedTask.call();
LOGGER.info("Finished timeBreachedTask");
} catch (Exception e) {
LOGGER.error("timeBreachedTask exception", e);
}
}
return;
}
try {
Thread.sleep(10);
}
catch (InterruptedException t) {}
}
}
}
I feel the approach in accepted answer is a bit outdated. With Java8, it can be done much simpler.
Say, you have a method
MyResult conjureResult(String param) throws MyException { ... }
then you can do this (keep reading, this is just to show the approach):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws Exception {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
}
of course, throwing Exception is bad, here is the correct extended version with proper error processing, but I suggest you examine it carefully, your may want to do some things differently (logging, returning timeout in extended result etc.):
private final ExecutorService timeoutExecutorService = Executors.newSingleThreadExecutor();
MyResult conjureResultWithTimeout(String param, int timeoutMs) throws MyException {
Future<MyResult> future = timeoutExecutorService.submit(() -> conjureResult(param));
try {
return future.get(timeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
//something interrupted, probably your service is shutting down
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (ExecutionException e) {
//error happened while executing conjureResult() - handle it
if (e.getCause() instanceof MyException) {
throw (MyException)e.getCause();
} else {
throw new RuntimeException(e);
}
} catch (TimeoutException e) {
//timeout expired, you may want to do something else here
throw new RuntimeException(e);
}
}

Categories

Resources