I am trying to create a new thread process, after thread process ends i want to get a result from that class.how can i do it?
For example this two classes. Lets say abThread class returns String array. How should I get those String values.
Class A{
public static void main(String[] args){
abThread bb=new abThread();
bb.start();
// when bb.run() returns data catch it
}
}
Class abThread extends Thread{
public void run(){
**// do smth here**
// then return result to the main Class
}
}
What you are looking for is a Callable like so:
public class MyCallable implements Callable<String[]>
{
#Override
public String [] call() throws Exception
{
//Do your work
return new String[42]; //Return your data
}
}
public static void main(String [] args) throws InterruptedException, ExecutionException
{
ExecutorService pool = Executors.newFixedThreadPool(1);
Future<String[]> future = pool.submit(new MyCallable());
String[] myResultArray = future.get();
}
Related
This question already has answers here:
java.lang.IllegalThreadStateException
(6 answers)
Closed 2 years ago.
I am trying to create a game and have come across a bizarre issue with the way I choose to run my Threads
The way I have it set up is that each pertinent class has a Thread Object, who's run() function runs the code once. Each is called once every frame.
However whenever I try to run the code I get a java.lang.IllegalThreadStateException and I have no clue why.
Here's an adaptation of the problematic code:
public class Test {
public static void main(String[] args) {
while(true) {
ThreadA.run(args);
ThreadB.run(args);
}
}
private static class ThreadA {
private static Thread thread = new Thread() {
#Override
public void run() {
System.out.println("A");
}
};
public static void run(String[] args) {
thread.start();
}
}
private static class ThreadB {
private static Thread thread = new Thread() {
#Override
public void run() {
System.out.println("B");
}
};
public static void run(String[] args) {
thread.start();
}
}
}
The problem is here:
while(true) {
ThreadA.run(args);
ThreadB.run(args);
}
This will loop infinitely. It is never legal to start a thread more than once - even if it has completed. thread.isAlive() won't help you here - if you want to run it again, make a new instance.
You're calling Thread#start over and over. It's throwing IllegalStateException because the threads internal status must be equal to 0 for it to start. Anything other than 0 means it has run, is running, or is disposed of.
As per JavaDoc:
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution.
If you intend to run the threads infinitely, you can do it as
public class Test {
public static void main(String[] args) {
ThreadA.run(args);
ThreadB.run(args);
}
private static class ThreadA {
private static Thread thread = new Thread() {
#Override
public void run() {
while (true) {
System.out.println("A");
}
}
};
public static void run(String[] args) {
thread.start();
}
}
private static class ThreadB {
private static Thread thread = new Thread() {
#Override
public void run() {
while (true) {
System.out.println("B");
}
}
};
public static void run(String[] args) {
thread.start();
}
}
}
I have a static variable which I would like to set in a run() method. I have the following:
public class Test{
public static int temp;
public static void main(String [] args)
{
update();
System.out.println("This is the content of temp"+temp);
}
public static void update()
{
(new Thread() {
#Override
public void run() {
// do some stuff
Test.temp=15;
}}).start();
}
I would like the content of temp to be updated to 15; but when I print it in the main function, it shows 0. How can this be fixed?
Threads working concurrently so you should wait until your new thread finishes:
public class Test{
public static int temp;
public static void main(String [] args) {
update().join(); //we wait until new thread finishes
System.out.println("This is the content of temp"+temp);
}
public static Thread update() {
Thread t = new Thread() {
#Override
public void run() {
// do some stuff
Test.temp=15;
}
};
t.start();
return t;
}
You have to understand how Thread works.
I will show you two pieces of code here first is to understand, variables that are initialized inside the thread takes take time to update until the thread is finished.
public class Num {
public static int temp;
public static void main(String [] args) throws InterruptedException
{
update();
System.out.println("This is the content of temp"+Num.temp);//This will print before temp=15 is updated
}
public static void update()
{
(new Thread() {
#Override
public void run() {
// do some stuff
Num.temp=15;
System.out.println("Value of temp:"+Num.temp);//This statement prints after
}}).start();
}
}
It Prints the following:
This is the content of temp0
Value of temp:15
Second one shows, if you wait for a small amount time(Thread.sleep(10)) after the thread is executed, the value gets updated:
public class Num {
public static int temp;
public static void main(String [] args) throws InterruptedException
{
update();
Thread.sleep(10);
System.out.println("This is the content of temp"+Num.temp);//This will print correct value now
}
public static void update()
{
(new Thread() {
#Override
public void run() {
// do some stuff
Num.temp=15;
}}).start();
}
}
But here I would suggest the same method as Philip did. Just add throws InterruptedException in main function
I am working on a project in which I have multiple interface and two Implementations classes which needs to implement these two interfaces.
Suppose my first Interface is -
public Interface interfaceA {
public String abc() throws Exception;
}
And its implementation is -
public class TestA implements interfaceA {
// abc method
}
I am calling it like this -
TestA testA = new TestA();
testA.abc();
Now my second interface is -
public Interface interfaceB {
public String xyz() throws Exception;
}
And its implementation is -
public class TestB implements interfaceB {
// xyz method
}
I am calling it like this -
TestB testB = new TestB();
testB.xyz();
Problem Statement:-
Now my question is - Is there any way, I can execute these two implementation classes in parallel? I don't want to run it in sequential.
Meaning, I want to run TestA and TestB implementation in parallel? Is this possible to do?
Sure it is possible. You have actually many options. Preferred one is using callable and executors.
final ExecutorService executorService = Executors.newFixedThreadPool(2);
final ArrayList<Callable<String>> tasks = Lists.newArrayList(
new Callable<String>()
{
#Override
public String call() throws Exception
{
return testA.abc();
}
},
new Callable<String>()
{
#Override
public String call() throws Exception
{
return testB.xyz();
}
}
);
executorService.invokeAll(tasks);
This method gives you opportunity to get a result from executions of your tasks. InvokeAll returns a list of Future objects.
final List<Future<String>> futures = executorService.invokeAll(tasks);
for (Future<String> future : futures)
{
final String resultOfTask = future.get();
System.out.println(resultOfTask);
}
You can make your code easier to use if you make your classes implements Callable, then you will reduce amount of code needed to prepare list of tasks. Let's use TestB class as an example:
public interface interfaceB {
String xyz() throws Exception;
}
public class TestB implements interfaceB, Callable<String>{
#Override
public String xyz() throws Exception
{
//do something
return "xyz";
}
#Override
public String call() throws Exception
{
return xyz();
}
}
Then you will need just
Lists.newArrayList(new TestB(), new TestA());
instead of
final ArrayList<Callable<String>> tasks = Lists.newArrayList(
new Callable<String>()
{
#Override
public String call() throws Exception
{
return testA.abc();
}
},
new Callable<String>()
{
#Override
public String call() throws Exception
{
return testB.xyz();
}
}
);
Whats more, executors gives you power to maintain and reuse Thread objects which is good from performance and maintainability perspective.
Create Two Thread and run two implementation parallely. Code snippet -
ThreadA{
public void run(){
TestA testA = new TestA();
testA.abc();
}
}
...
ThreadB{
public void run(){
TestB testB = new TestB();
testB.xyz();
}
}
Start this two thread from main method -
public static void main(String[] args){
new ThreadA().start();
new ThreadB().start();
}
Try this one
Collect all the classes of same interface and call them in Multi threading.
Use Callback mechanism to get the result back
import java.util.ArrayList;
import java.util.List;
public class Demo123 {
public static void main(String[] args) {
List<InterfaceA> a = new ArrayList<InterfaceA>();
List<InterfaceB> b = new ArrayList<InterfaceB>();
TestA testA = new TestA();
TestB testB = new TestB();
a.add(testA);
b.add(testB);
for (final InterfaceA i : a) {
new Thread(new Runnable() {
#Override
public void run() {
try {
i.callback(i.abc());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
for (final InterfaceB i : b) {
new Thread(new Runnable() {
#Override
public void run() {
try {
i.callback(i.xyz());
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
}
}
interface MyCallback {
public void callback(String value);
}
interface InterfaceA extends MyCallback {
public String abc() throws Exception;
}
class TestA implements InterfaceA {
#Override
public String abc() throws Exception {
return "abc";
}
#Override
public void callback(String value) {
System.out.println("value returned:" + value);
}
}
interface InterfaceB extends MyCallback {
public String xyz() throws Exception;
}
class TestB implements InterfaceB {
#Override
public String xyz() throws Exception {
return "xyz";
}
#Override
public void callback(String value) {
System.out.println("value returned:" + value);
}
}
You may try it like this:
public static void main(String[] args) throws InterruptedException {
Executors.newCachedThreadPool().invokeAll(Arrays.asList(
new Callable<String>() {
#Override public String call() { return new TestA().abc(); }
},
new Callable<String>() {
#Override public String call() { return new TestB().xyz(); }
}));
}
public interface InterfaceA {
public String abc() throws Exception;
}
public interface InterfaceB {
public String xyz() throws Exception;
}
class TestA implements InterfaceA {
#Override public String abc() {
System.out.println("Inside A"); return null;
}
}
class TestB implements InterfaceB {
#Override public String xyz() {
System.out.println("Inside B"); return null;
}
}
I have a class, such as:
public class Test {
private static Thread aThread;
private static Loopy aLoop;
public Test() {
}
public static void main(String[] args) {
startUpdate();
stopUpdate();
startUpdate();
}
public static void startUpdate() {
aLoop = new Loopy();
aThread = new Thread(aLoop);
aThread.start();
}
public static void stopUpdate() {
if (aThread != null) {
aLoop.finish();
}
}
}
with runnable code that looks like:
public class Loopy implements Runnable {
private static String status = "R"; // Run
public void run() {
while (status.equals("R")) {
// Do Stuff
}
}
public void finish() {
status = "F"; // End Run
}
}
Calling startUpdate works the first time.
StopUpdate works as planned.
Calling startUpdate the second time results in no work being done as status is still equal to "F" from the stop, even though I am starting a new instance of Loopy which (to me) should have the default value of "R".
Is the status persisting across instances, or have I made an error I haven't spotted yet?
You have overused static.
In your Loopy class the String status is static and is therefore shared across all Loopy instances.
You should make status an instance variable by removing the static.
Another note is that status should also be volatile as it's state is changed by numerous threads without synchronization.
I would also suggest that maybe you should make all the variables/methods in Test instance too (except main) as it's generally best to avoid static where possible:
public class Test {
private Thread aThread;
private Loopy aLoop;
public static void main(String[] args) {
final Test test = new Test();
test.startUpdate();
test.stopUpdate();
test.startUpdate();
}
public void startUpdate() {
aLoop = new Loopy();
aThread = new Thread(aLoop);
aThread.start();
}
public void stopUpdate() {
if (aThread != null) {
aLoop.finish();
}
}
}
I think status shoud not be static
I have a class like this , where I am updating a static variable in a thread. And I need to access this variable from another class.
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread( VariableUpdater.getInstance());
th.start();
}
#Override
public void run() {
while (true) {
System.out.println();
try {
abc.add("aa");
Thread.sleep(1000);
printContent();
} catch (Exception e) {
// TODO: handle exception
}
}
}
public synchronized void printContent() {
for (String string: abc) {
System.out.println(string);
}
}
}
And this variable needs to be accessed from another class like this :
public class Accessor {
public static void main(String[] args) {
VariableUpdater.getInstance().printContent();
}
}
The problem is, when running the Accessor class the list is empty.
Am I missing something here?
UPDATE/Solution
It turns out we can achieve this by using Hazelcast or some sort of messaging/caching utility. I will post a full solution soon.
Source: How to share object between java applications?
From this code u can access the List in another class object
import java.util.ArrayList;
import java.util.List;
public class VariableUpdater implements Runnable {
static List < String > abc = new ArrayList < String > ();
private static VariableUpdater instance = null;
private VariableUpdater() {}
public static synchronized VariableUpdater getInstance() {
if (instance == null) {
instance = new VariableUpdater();
}
return instance;
}
public static void main(String[] args) {
Thread th = new Thread(new VariableUpdater());
th.start();
Accessor.print();
}
#Override
public void run() {
for(int i=0;i<10;i++) {
System.out.println();
try {
abc.add("aa");
// Thread.sleep(1000);
//printContent();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized void printContent() {
System.out.println("List :: " + abc);
}
}
class Accessor {
public static void print() {
System.out.println("Accessor");
VariableUpdater.getInstance().printContent();
}
}
You have two main() methods in two different classes. On running two main() methods there will be two instances of JVM and those do not share anything. So your list will always be empty.
Use one main() method to start threads.
public class Main{
//shared state
public static void main(String[] args){
VariableUpdator variableUpdatorInstance = ...
Accessor accessorInstance = ...
variableUpdatorInstance.start();
accessorInstance.start();
//or in your case
new Thread(new VariableUpdater()).start();
Thread.sleep(9000); //runs eventually after 9 seconds
Accessor.print();
}
}
UPDATE:
class Thread1 extends Thread{
static List<String> list = new ArrayList<String>();
}
class OtherClass{
public void someMethod(){
Thread1.list; //this is how you access static variable of one class in other
}
}