Controlling the execution of a method via Threads in Java - java

I need to have two classes, one class has two methods each of which will take a while to execute completely. The second class is given information which will decide which one of the two methods in the first class will execute. It is important however that if the second class (which will be executing at the same time in its own thread) decides that the other of the two methods should execute, the first class would go straight to executing the other method and not have to wait for the first to finish.
If class A has the two methods and class B is in parallel in a different thread deciding which method to execute then here is an example:
A is executing method 1 which will take a while to return. During the execution of method 1, class B decides method 2 should execute which means class A should immediately stop doing method 1 and go on to execute method 2.
Is this possible? Maybe with interrupts?
thanks

If you make Class A implement runnable and then execute its method by having Class B create a new Thread with an object of type Class A, you can have Class B call the interrupt method on the Class A thread.

Here's an outline of something that should work:
class ClassA implements Runnable {
public volatile boolean switchToOther;
#Override
public void run() {
switchToOther = false;
try {
method1();
} catch (InterruptedException e) {
// Restore the interrupted status
Thread.currentThread().interrupt();
}
if (switchToOther) {
method2();
}
}
public void method1() throws InterruptedException {
work();
}
public void method2() throws InterruptedException {
otherWork();
}
}
class ClassB implements Runnable {
#Override
public void run() {
ClassA a = new ClassA();
Thread t = new Thread(a);
t.start();
if (decideToSwitch()) {
a.switchToOther = true;
t.interrupt();
}
}
}
Note:
InterruptedException can happen beyond your control, so you should check it's due to an explicit switch,
the volatile on the switchToOther field used from several threads,
the resetting of the interrupted state, which is standard idiom when catching InterruptedException

Related

Calling a method of a class which extends Thread, from another class

I know this is a bit naive question but I want to understand the basic working principle behind multi-threading in java. Consider the following code and say A is executed in Main thread and it starts execution of another worker thread ,defined in class B. I want to know that can B.func1 called from A and run method of B, be executed in parallel or not?
public class A {
public static void main(String[] args) {
B obj = new B();
obj.start();
obj.func1();
}
}
public class B extends Thread {
public B() {
//constructor
}
public void run() {
while(true) {
//do somethings
}
}
public void func1() {
//do someotherthings
}
}
There is no magic behind a method call. If you call method from a thread, it is called in exactly the same thread. So since obj.func1() is called from main, it will be run in the main thread. It doesn't matter which class it belongs to or whether or not it extends Thread.
The new thread starts by executing run. Everything called from run and so on will be executed in parallel to main.
It's important to understand the difference between a thread and a Thread.
A thread is an independent execution of your code. Often when we talk about how some method or another works we say things like, "It tests the variable x, and if x is less than zero it calls the foobar method..."
Ok, but what is the "it" in that sentence? It is not the method. Methods don't do anything. A method is just a list of instructions, like the list of chores that somebody left for their housemate to perform. The list doesn't do the chores, it's the housemate that does the work (or so we might hope).
The "it" is a thread. Threads are entities in the operating system that execute methods (i.e., they do the chores).
A Thread, on the other hand, is a Java object that your program can use to create and manage new threads. Your program creates a new Thread object by doing:
thread t = new Thread(...);
[Oops! See what I just did? It's not your program, that does the work, it's your program's main thread, or maybe some other thread in your program. It's an easy thing to forget!]
Anyway, it subsequently creates the new thread by calling t.start();
Once you understand all that, then Sergey Tachenov's answer becomes obvious: Calling the methods of a Thread object really is no different from calling methods of any other kind of object.
There are multiple issues with your code. I have corrected them and added one more statement to print Thread Name in func1().
Working code:
public class A {
public static void main(String args[]){
B obj = new B();
obj.start();
obj.func1();
}
}
class B extends Thread{
public B (){
//constructor
}
public void run(){
while(true){
//do somethings
}
}
public void func1 (){
//do someotherthings
System.out.println("Thread name="+Thread.currentThread().getName());
}
}
output:
Thread name=main
Since you are directly calling func1() from main method (A.java) , you will get Thread name = main in output.
If you add same print statement run() method, you will get output as : Thread name=Thread-0

Accessing an object from another thread

I've got 2 classes (1 is a basic class, 2nd one extends Thread class) and I'm trying to access an object (class) that is initialized in my thread class on run() using setText()
public class TThread extends Thread{
Patcher pf;
public TThread(String string) {
setName(string);
start();
}
#Override
public void run() {
pf = new Patcher("Checking Serial key..."); //<=== Class initialized here in a separate thread
}
public void setText(String string) {
pf.setText(string); //<=== Trying to access patcher here, throws NullPointerException
}
}
This is how I call TThread
public void myCall(){
TThread tpf = new TThread("pf thread");
//some code later
try{
tpf.setText("blabla");
}
The pf.setText() throws NullPointerException when I'm trying to access patcher from another thread.
How can I get to that thread and access patcher from another class or this class?
This is classic race condition. Because you have two threads, there is no guarantee what will happen first. pf might be accessed by main thread before it's initialized by a background thread.
Right now, your program is unpredictable. Try adding Thread.sleep(100); at the beginning of setText method. It will appear to work correctly, but it might still fail in some specific circumstances.
One way to fix it is to wait in main thread until pf is initialized:
#Override
public synchronized void run() {
pf = new Patcher("Checking Serial key...");
notifyAll();
}
public synchronized void setText(String string) throws InterruptedException {
while(pf==null) {
wait();
}
pf.setText(string);
}
Be careful. If you have not worked with threads before, it might be tricky to get right.
It is a time consuming process to start a new Thread. With a small delay your code will execute successfully:
TThread thread = new TThread("str");
Thread.sleep(1000);
thread.setText("str2");
So the problem is that your thread had no time to execute the run method (and create the instance). You should check the existance of the instance, and wait for it's creation in the setText method - or instantiate it in the TThread's constructor.

ThreadFactory and newThread(Runnable r) how to access to the attributes of r if it is a Thread?

For my thesis I'm working on a Discrete Event System Simulator. The simulation consists in a set of SimulatorThread extends Thread whose action consist in scheduling Events to the Simulator. Each SimulatorThread interracts with the Simulator through the SimulatorInterface.
public abstract class SimulatorThread extends Thread {
private SimulatorInterface si;
public SimulatorThread(SimulatorInterface si) {
this.si = si;
}
...
}
public final class Simulator {
private ExecutorService exec;
...
public void assignThread(SimulatorThread... stList) {
...
}
}
Before the simulation begins, each SimulatorThread is assigned to the Simulator, then the Simulator will execute each thread through exec.execute(simulatorThread). My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption. Infact the output of System.out.print(Thread.currentThread().getClass()) is class java.lang.Thread, but I would like that the output is class SimulatorThread which can be obtained by running the thread using the instruction simulatorThread.start() instead of using the executor. So I thought that the problem is in writing an ad-hoc ThreadFactory that return an instance of SimulatorThread.
Infact I tried to use the trivial SimulatorThreadFactory extends ThreadFactory:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new SimulatorThread(new SimulatorInterface());
}
}
and with this I obtained the previously cited output 'class SimulatorThread'. The problem is that when I call 'exec.execute(simulatorThread)', the parameter has an attribute 'SimulatorInterface' to which I need to get access, but I can't becaues the parameter of the method 'newThread' is a 'Runnable'. I expose here a wrong code that I hope expresses what I mean better than how I explain in words:
public class SimulatorThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
SimulatorInterface si = r.getSimulatorInterface(); // this is what
// I would like
// the thread factory
// to do
return new SimulatorThread(si);
}
}
So, how can I access to attribute 'SimulatorInterface' of the 'SimulatorThread' inside the method newThread in order to create a SimulatorThread if its paramater is a Runnable?
If I understand your needs, the right way to do this is to not extend Thread but to implement Runnable. Then all of the benefits of your own class hierarchy can be enjoyed:
public abstract class SimulatorRunnable extends Runnable {
protected SimulatorInterface si;
public SimulatorRunnable(SimulatorInterface si) {
this.si = si;
}
}
public final class Simulator extends SimulatorRunnable {
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
// here you can use the si
si.simulate(...);
}
}
Then you submit your simulator to your thread-pool:
Simulator simulator = new Simulator(si);
...
exec.submit(simulator);
My problem is that in some part of the code i need to get a reference to the current running SimulatorThread, but the instruction (SimulatorThread) Thread.currentThread() gives a cast execption
You should not be passing a Thread into an ExecutorService. It is just using it as a Runnable (since Thread implements Runnable) and the thread-pool starts its' own threads and will never call start() on your SimulatorThread. If you are extending Thread then you need to call thread.start() directly and not submit it to an ExecutorService. The above pattern of implements Runnable with an ExecutorService is better.
#Gray's answer is correct, pointing out that the ExecutorService is designed to use its own threads to execute your Runnables, and sometimes created threads will even be reused to run different Runnables.
Trying to get information from (SimulatorThread) Thread.currentThread() smells like a 'global variable' anti-pattern. Better to pass the 'si' variable along in method calls.
If you really want global variables that are thread-safe, use ThreadLocals:
public final class Simulator extends SimulatorRunnable {
public static final ThreadLocal<SimulatorInterface> currentSim = new ThreadLocal<>();
public Simulator(SimulatorInterface si) {
super(si);
}
public void run() {
currentSim.set(si)
try{
doStuff();
}
finally{
currentSim.unset();
}
}
private void doStuff()
{
SimulatorInterface si = Simulator.currentSim.get();
//....
}
}

Invoking different methods within one runnable thread in java

As far as my understanding is so far; a class which implements runnable seems to only be able to perform one set task within its run method. How is it possible to create a new thread and then run different methods from this one additional thread, without needing to create some new runnable class for every set task.
Make your own subclass of Thread (MyThread extends Thread)
Add private members to control the behavior.
Add bean-pattern get/set methods to control the private members, or use a fluent API.
Read this properties in the run() method.
MyThread t = new MyThread();
t.setTypeOfSparrow("African");
t.setFavoriteColor("Yellow");
t.start();
Your Runnable class can call any logic it likes. The logic you want to run must be in some class, could be different methods of the Runnable class or could be in lots of other classes.
How did you plan to tell the runnable what to do?
You could do something like:
MyRunnable implements Runnable {
private String m_whatToDo;
public MyRunnable(String whatToDo) {
m_whatToDo = whatToDo;
}
public void Runnable run() {
if ("x".equals(m_whatToDo) {
// code to do X
} else if ( "y".equals(m_whatToDo) {
// code to do Y
} else {
// some error handling
}
}
}
Or as Srikanth says you could communicate the intent by other means such as thread names.
However I don't see much overhead in creating a runnable class. Just adding a public void run() to a class is surely not that big a deal?
A class should perform one task and perform it well, and if you are adding multiple operations in a single Runnable then you are violating this principle. You should create a new implementation of Runnable for each runnable task.
To simplify your api you might like to create a MyRunnableFactory method which constructs a runnable class depending on one or more construction criteria. This would shield the user from having to remember which class to create for each task.
Your question isn't quite clear. My guess is that you want to run different methods in some other thread, but you don't want to waste time restarting a new thread for each method. In that case you need an ExecutorService with one thread. You can submit sequentially some Runnables to a thread that is kept alive between calls.
Or more simply if you already know the order in which your methods are called
(new Thread() {
#Override public void run() {
method1();
method2();
...
}
}).start();
In the run() method check for the thread name and call the appropriate method.
public class SampleThread implements Runnable{
/**
* #param args
*/
Thread t=null;
public SampleThread(String threadName)
{
t=new Thread(this,threadName);
t.start();
}
#Override
public void run() {
if(t.getName().equals("one"))
{
One();
}
else if(t.getName().equals("two"))
{
Two();
}
}
public void One()
{
System.out.println(" ---- One ---- ");
}
public void Two()
{
System.out.println(" ---- Two ---- ");
}
public static void main(String[] args) {
SampleThread t1=new SampleThread("one");
SampleThread t2=new SampleThread("two");
}
}

how to override thread.start() method in java?

I need to implement thread.start() method in my java code. Please let me know through an example of overriding of thread.start() method and how it works?
You should not. Override run instead
You can override start as any other method
Thread myThread = new Thread() {
#Override
public void start() {
// do something in the actual (old) thread
super.start();
}
#Override
public void run() {
// do something in a new thread if 'called' by super.start()
}
};
but you must call super.start() to create a new thread and have run() called in that new thread. The original start does some magic (native code) that you hardly can mimic.
If you call run() directly from within your start() (or any other method), it is executed in the actual thread as a normal method, not in a new thread. There is no reason to use a Thread if you don't want to run some code in a new thread.
You must put your decision logic in the run() method, maybe using some variable set in the constructor (or another method, eventually in start) if that is really needed. I can not find any reason for needing this variable, it should be enough to test the condition in run() as already suggested elsewhere.
class MyThread extends Thread {
private final boolean flag;
public MyThread(boolean someCondition) {
flag = someCondition;
}
// alternative
// #Override
// public synchronized void start() {
// flag = <<someCondition>>
// super.start();
// }
#Override
public void run() {
if (flag) {
// do something like super.run()
} else {
// do something else
}
}
}
but it would be easier to understand and maintain if you do it like #Henning suggested!
It's also a more object oriented solution...
As others said, overriding Thread.start() is not the way to do it. Usually, I wouldn't override Thread.run() either, but use a Runnable.
If you have to decide which method to run after the thread has been spawned, you could do something like this:
final Runnable runnableA = ...;
final Runnable runnableB = ...;
Runnable r = new Runnable() {
#Override
public void run() {
if (...) {
runnableA.run();
} else {
runnableB.run();
}
}
}
Thread thread = new Thread(r);
thread.start();
If, as you say, you have a superclass and a subclass where the run() method is overidden, you can just rely on late binding and the proper method will be invoked automatically:
Runnable couldBeAOrB = ...;
Thread thread = new Thread(couldBeAOrB);
thread.start();
You don't override the start, you override the "run". You can simply implement a thread by:
new Thread() {
public void run() {
//your code here
}
}.start();
//start will call the logic in your run method
Actually, you can call run() to run a thread instead of start() to run a thread. But there is a little difference.
Suppose you create two threads:
Thread t1 = new Thread();
Thread t2 = new Thread();
Case 1 : If you call "t1.run()" and "t2.run()" one after another they will start to run t1 and t2 synchronously (sequentially).
Case 2 : If you call "t1.start()" and "t2.start()" one after another they will call their run() methods and start to run t1 and t2 asynchronously (in parallel).
Agree with Schildmeijer, don't override start, override run() instead.
In fact, although start can be overridden (it's not final), it calls the native start0 method which in turn will cause the VM to call the run method (actually from the context of a native thread/process). The native start0 method has private access, so even if you overrode the start, I can't see how you could reproduce the affect.
The client calling start() is within a thread (lets say, the main thread), it's not until the run method has done its thing that another thread will be spawned.
Take a look at the Sun (ahem, Oracle) tutorial on threads at http://download.oracle.com/javase/tutorial/essential/concurrency/index.html, in particular the section on starting threads.
class Worker implements Runnable{
public void run(){
if("foo"){
runFoo();
} else {
runBar();
} }
private void runFoo(){
// something }
private void runBar(){
// else }
}
I'm pretty sure, you needn't to overwrite the start-Method.
By the way: Take al look at java.util.concurrent.Callable
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/Callable.html
It is discouraged to override Thread, if possible create an implementation of the Runnable interface instead and run that on a thread. This can also be done with a lambda expression, making everythin super short and simple.
// create a new thread and give it a Runnable with a lambda expression and a custom name
Thread thread = new Thread(() -> {
// put your code here
}, "CustomThreadName");
// start it
thread.start();
If we provide our own implementation of start method then it will work like a normal method call and will work on the current thread stack only. New thread will not be created.
Yes the start() method can be overridden. But it should not be overridden as it is implementation in thread class has the code to create a new executable thread and is specialised.
We can override start/run method of Thread class because it is not final. But it is not recommended to override start() method
class Bishal extends Thread {
public void start()
{
System.out.println("Start Method");
}
public void run()
{
System.out.println("Run Method");
}
} class Main{
public static void main(String[] args)
{
Bishal thread = new Bishal();
thread.start();
System.out.println("Main Method");
}
}
when we are calling start() method by an object of Bishal class, then any thread won’t be created and all the functions are done by main thread only.

Categories