Thread Safe Accessing Enums in Java - java

I want to know that the following code can be used in multi-threaded environment thread safely. I hope to use Task class as an accessing layer.
public class Task {
public static enum TaskList {
TASK_A {
#Override
void doProcess() {
System.out.println("processing task A");
}
},
TASK_B {
#Override
void doProcess() {
System.out.println("processing task B");
}
},
TASK_C {
#Override
void doProcess() {
System.out.println("processing task C");
}
};
abstract void doProcess();
}
}
This is how it is going to be used.
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
//following code will be executed in multiple threads.
Task.TaskList task = Task.TaskList.TASK_A;
task.doProcess();
}
});
thread.start();
}

Using enums has little to do with thread safety.
Your code (as presented here in the question) is thread-safe. But the following isn't:
public class Task {
public static enum TaskList {
TASK_A {
int x = 0;
#Override
void doProcess() {
x++;
System.out.println("processing task A: " + x);
}
};
abstract void doProcess();
}
}
As you see, it being an enum has no bearing on thread safety. What matters is whether the object (enum value in this case) has any internal state that can change without being properly synchronized, and whether everything that the actual code calls is thread-safe as well.

Related

Access synchronized method from another thread using same instance

I've a core method in my project which I need it to be synchronized in order not to be accessed twice at the same time, and hence I have a thread which uses an instance from this class to access this method, but inside this thread I need to have a long life loop to be used to access the same method with a fixed value so I have to use another thread in order to allow the first thread to move on and complete it's duties, but for sure the method doesn't run from that second thread using the same instance used in the first thread, and somehow I can't instantiate another instance from the class as I have to use this instance exactly, so how to overcome this problem.
below is the problem translated to java:
public class ClassOne {
synchronized public void my_method(int number) {
// Do some Work
}
}
public class ClassTwo {
private void some_method() {
Thread one = new Thread(new Runnable() {
#Override
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
boolean running = true;
private void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
#Override
public void run() {
while (running) {
class_one.my_method(1); // won't run
Thread.sleep(10000);
}
}
});
two.start();
}
}
Actual problem overview:
my_method --- > is to send UDP packets.
the method has to be synchronized otherwise I'll get the socket is already open exception when trying to use it more than once repeatedly.
at some point, I have to send a KeepAlive message repeatedly each 10 seconds, so, I have to launch a separate thread for that which is thread two in run_loop method.
Putting something that will compile and work. I don't see why you need this function to be synchronized. Check the output for this program...The second thread access this method only when the first thread is done accessing (unless you have missed adding some additional code).
class ClassOne {
int criticalData = 1;
synchronized public void my_method(int number) {
// Do some Work
criticalData *= 31;
System.out.println("Critical data:" + criticalData + "[" + Thread.currentThread().getName() + "]");
}
}
class ClassTwo {
boolean running = true;
public void some_method() {
Thread one = new Thread(new Runnable() {
public void run() {
ClassOne class_one = new ClassOne();
// DO Work
class_one.my_method(0);
run_loop(class_one);
// Complete Work
}
});
one.start();
}
public void run_loop(final ClassOne class_one) {
Thread two = new Thread(new Runnable() {
public void run() {
while (running) {
class_one.my_method(1); // won't run
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
two.start();
}
}
public class StackExchangeProblem {
public static void main(String[] args) {
ClassTwo two = new ClassTwo();
two.some_method();
}
}

Why doesn't run method call?

I've write the following example:
public class MyThread extends Thread{
MyThread(Runnable r){
super(r);
}
public void run(){
System.out.println("run");
}
}
public static void main(String[] args)
{
Thread t = new MyThread(new Runnable() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
});
t.start(); //run
}
Why does run methdo defined in MyThread was called instead?
Because the default behavior of a thread constructed with a Runnable is to delegate to the runnable passed as argument to the constructor. But you overrode run() in the thread itself, so instead of delegating to the runnable, it executes the code inside the overridden run() method.
For the record, here's the default implementation of Thread.run(), that you overrode:
private Runnable target;
public void run() {
if (target != null) {
target.run();
}
}
Because you the MyThread.run is not override, but the Runnable.run is. Now if you look at your implementation of MyThread.run, the stored Runnable plays no part in it. In other words, it doesn't matter what kind of runnable you give with the constructor. You should use:
public static void main(String[] args)
{
Thread t = new MyThread() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
});
t.start(); //run
}
As #BorisTheSpider notes, overriding a Thread is in general not good practice: a Thread has the responsibility to start a Thread and give control to a runnable. A better implementation would be:
public static void main(String[] args)
{
Thread t = new Thread(new MyThread() {
#Override
public void run() {
System.out.println("rrrrrrrrrruuuuuuuuuuuun");
}
}));
t.start(); //run
}

Using Listener with Threads

Say I have an Object Foo that wants to get informed by several running instances of a Thread using a listener interface. E.g.
The interface:
public interface ThreadListener {
public void onNewData(String blabla);
}
The class Foo:
public class Foo implements ThreadListener {
public Foo() {
FooThread th1 = new FooThread();
FooThread th2 = new FooThread();
...
th1.addListener(this);
th2.addListener(this);
...
th1.start();
th2.start();
...
}
#Override
public void onNewData(String blabla) {
...
}
}
The Thread:
public FooThread extends Thread {
private ThreadListener listener = null;
public void addListener(ThreadListener listener) {
this.listener = listener;
}
private void informListener() {
if (listener != null) {
listener.onNewData("Hello from " + this.getName());
}
}
#Override
public void run() {
super.run();
while(true) {
informListener();
}
}
}
In the worst case onNewData(..) is invoked by several threads at the same time. What will happen with Foo? Is it going to crash or not?
Your Foo class has no state (fields), so unless it uses external shared resources (e.g. files...) it is thread safe
Starting thread from a constructor is generally a bad idea although in the case of a state-less object, I suppose it is fine
if onNewData does not access shared data it will work as expected, if it does, the outcome will depend on how the method is implemented.

Multiple Runnable in a single thread -java

I am trying to have a bunch of runnable threads that can be started one at a time.
Something like
First(new Thread() {
public void run() {
//do something
}
});
Is what I'm trying to do impossible?
You can use a single threaded Executor
ExecutorService service = Executors.newSingleThreadedPool();
service.submit(runnable1);
service.submit(runnable2);
service.submit(runnable3);
i want to have several runnables in one thread. they will be doing different things at different times.
This sounds like a bad design to me. If your class is doing different things at different times then it should be split into different classes.
If you are talking about re-using the same background thread to do different things, then I would use a single threaded pool as in #Peter's answer:
private ExecutorService threadPool = Executors.newSingleThreadedPool();
...
threadPool.submit(new First());
threadPool.submit(new Second());
threadPool.submit(new Third());
...
// when you are done submitting, always shutdown your pool
threadPool.shutdown();
The First, Second, and Third classes would implement Runnable. They can take constructor arguments if they need to share some state.
Yes, just have multiple private methods:
public class FirstCaller {
private void method1() { }
private void method2() { }
private void method3() { }
public void someMethod() {
First(new Thread() {
public void run() {
//do something
method1();
method2();
method3();
}
});
}
}
OR as pointed out by Ted Hopp
public class FirstCaller {
public void someMethod() {
new First(new Thread() {
private void method1() { }
private void method2() { }
private void method3() { }
public void run() {
//do something
method1();
method2();
method3();
}
});
}
}
If you want to start a few threads at the same time CountDownLatch is what you need. See an example here: http://www.javamex.com/tutorials/threads/CountDownLatch.shtml.
Are you trying to execute multiple runnables sequentially in a single Thread? One after the other?
public class MultiRunnable implements Runnable {
private Runnable runnable1;
private Runnable runnable2;
public MultiRunnable(Runnable runnable1, Runnable runnable2) {
this.runnable1 = runnable1;
this.runnable2 = runnable2;
}
#Override
public void run() {
runnable1.run();
runnable2.run();
}
}
You could then call (new Thread(new MultiRunnable(... , ...))).start();
This will execute the first Runnable first, and when that is finnished it will execute the second.
Or generalised to more Runnables:
import java.util.Arrays;
import java.util.List;
public class MultiRunnable implements Runnable {
private List<Runnable> runnables;
public MultiRunnable(Runnable... runnables) {
this.runnables = Arrays.asList(runnables);
}
public MultiRunnable(List<Runnable> runnables) {
this.runnables = runnables;
}
#Override
public void run() {
for(Runnable runnable : runnables)
runnable.run();
}
}
The easiest thing to do is to define several Thread subclass instances and call the appropriate one depending on what you are trying to do.
However, if you really need a single Thread object that behaves differently in different circumstances, you can define a Thread subclass that has a state variable for controlling what it does.
class MyThread extends Thread {
public enum Action { A, B, C }
private Action mAction;
public void run() {
if (mAction == null) {
throw new IllegalStateException("Action must be specified");
}
switch (mAction) {
case A:
methodA();
break;
case B:
methodB();
break;
case C:
methodC();
break;
}
}
public void setAction(Action action) {
if (action == null) {
throw new IllegalArgumentException("Action cannot be null");
}
mAction = action;
}
private void methodA() { ... }
private void methodB() { ... }
private void methodC() { ... }
}
You could then create your thread and before calling start(), call setAction, passing one of the Action values.
As an alternative to a state variable, the run() method could examine external variables to determine the choice of action. Whether this makes sense (and whether it would be better) depends on your application.

How to notify all observers without holding the thread?

I have a thread inside a class like this-
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
The problem is I never get it to print the "success" message.
I assume, it is because all observers are being notified from inside of MyThread. So when down.download(2) is called from the observer inside MyMethod(), the previous thread is still running and the call is ignored.
How can I notify all observers from the main thread, not from the myThread?
You are calling down.download(2) from within the execution of MyThread, therefore the thread is still alive which means that your download method does nothing because of if(!myThread.isAlive()).
I would recommend you to use the Executor framework and Listenable Futures from Guava instead of creating threads manually. Example code from the Guava wiki:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
Note that Futures.addCallback(..) also has an overload which allows you to determine which executor should execute the callback, this seems to be what you want.

Categories