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
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();
}
}
}
This is not my actual code, but it shows what I want to do. Why does the Print method end up printing the original value instead of the updated one when run inside another method? When I run them both from PSVM, it prints the number 3 like I expected it to.
public int testOne = 0;
public static void main(String[] args) {
Main tester = new Main();
tester.Increase();
}
public void Increase() {
Main tester = new Main();
testOne = 3;
tester.Print();
}
public void Print() {
System.out.println(testOne);
}
}
Output seems to come out as 0, anyone know why this happens? Running it in repl.it if it is a compiler thing.
public void Increase() {
Main tester = new Main(); // new instance Main1, testOne = 0
testOne = 3; // current instance Main0, testOne = 3
tester.Print(); // calling Main1.Print() prints 0
}
The testOne assignment you do is the one in the current class, but you're actually calling the Print() function from a completely new instance of the class you created in the local scope.
What you want to do is this:
public void Increase() {
testOne = 3;
Print();
}
This Print() method will be called from the current class context.
The problem you're facing is scope. Read up on it here: https://www.geeksforgeeks.org/variable-scope-in-java/
You have two instances of your class, so therefore two testOne variables, but you're only printing one of them
Either you need to set the instance variable
public static void main(String[] args) {
Main tester = new Main();
tester.Increase();
// tester.Print(); // would print 0
}
public void Increase() {
Main tester = new Main();
tester.testOne = 3;
tester.Print();
}
public void Print() {
System.out.println(testOne); // prints 3
}
Or don't make another instance at all
public static void main(String[] args) {
Main tester = new Main();
tester.Increase();
}
public void Increase() {
this.testOne = 3;
this.Print();
}
public void Print() {
System.out.println(testOne);
}
Another approach can be using Static.
public static int testOne = 0;
public static void main(String[] args) {
Main tester = new Main();
tester.Increase();
}
public void Increase() {
Main tester = new Main();
testOne = 3;
tester.Print();
}
public void Print() {
System.out.println(testOne);
}
So I made a timer but now I want that when the timer gets to 0 to print out "boom" how do I do this?
public class Main {
static Thread thread = new Thread();
public static void main(String[] args) throws InterruptedException {
for(int i = 60;i>=0;i--) {
thread.sleep(1000L);
System.out.println(i);
}
}
}
Try the following:
static Thread thread = new Thread();
public static void main(String[] args) throws InterruptedException
{
for(int i = 60;i>=0;i--)
{
thread.sleep(1000);
System.out.println(i);
}
System.out.println("boom");
}
I have a component that some where inside it opens a thread to create Session,
I can not go in or change anything inside.
I need to find a way to suspend the work till the inner Thread is finished.
(Cant check if session created and therefor cant create loop to wait while !session)
public class Agenda {
Work work=new Work();
public void go(){
work.start();
}
}
public class Work extends Thread {
#Override
public void run() {
for(int i=0; i<10;++i)
System.out.print("!->!");
System.out.println("\n");
super.run();
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Hello SmartHead!!");
Agenda agenda=new Agenda();
agenda.go();
//synchronized (work) {
synchronized (agenda) {
System.out.println("Finished !!! ");
}
}
}
I stripped everything out to see if I could narrow down my problem and figure it out but I'm embarrassed to say I'm still stumped. Can someone please explain to me why my IDE cannot resolve 'start'? I'm sure it's a stupid mistake :(
public class main {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
class MessageLoop implements Runnable {
public void run(){
//Do stuff here
}
}
}
Instead of defining your class in your method body. Java variable names start with a lower case letter by convention. Comments start with // not \\. I think you wanted something like
public static void main(String[] args) {
Thread messageThread = new Thread(new MessageLoop());
messageThread.start();
}
static class MessageLoop implements Runnable {
public void run() {
// Do stuff here
}
}
Use following approaches.
Approach1
public static void main(String[] args) {
Thread MessageThread = new Thread(new MessageLoop());
MessageThread.start();
}
static class MessageLoop implements Runnable {
public void run(){
System.out.println("helllo");
}
}
Approach 2
public static void main(String[] args) {
Thread MessageThread2 = new Thread(new Runnable(){
public void run(){
System.out.println("helllo2");
}
});
MessageThread2.start();
}