This question already has answers here:
Program hangs if thread is created in static initializer block
(4 answers)
Closed 6 years ago.
This class does not initialize itself in the usual way, so it calls on the help of background thread.
From my understanding ,surely the program must print true ?
But If you ran the program, you found that it prints nothing; it just hangs.
public class Test {
private static boolean isInitialized = false;
static {
Thread t = new Thread(new Runnable() {
public void run() {
isInitialized = true;
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
System.out.println(isInitialized);
}
}
Can some one please explain why this is happening.
"The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field." Static Initialization Blocks
I guess that this program to start needs to first initialize the class Test. And so it tries first to execute static block but that block never exits (since it cannot set static member isInitialized as it is not ready yet).
So Test class is never fully initialized and therefore main method is not even starting to be executed.
The solution for you could be moving the instruction of waiting for your initialization thread to finish - to the main method. So it does not block the Test class from being fully initailzed.
package com.company;
public class Test {
private static boolean isInitialized = false;
static Thread t = new Thread(new Runnable() {
public void run() {
isInitialized = true;
}
});
static {
t.start();
}
public static void main(String[] args) {
try {
t.join();
} catch (InterruptedException ignored) { }
System.out.println(isInitialized);
}
}
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 question already has answers here:
Java Wait and Notify: IllegalMonitorStateException
(2 answers)
Closed 4 years ago.
Was trying to practice producer and consumer using a simple counter in java.
Not sure why I am getting a Illegal Monitor State exception on this piece of code.
I have counter rest and counter consume methods which run in their own thread.
The counter itself is a static int volatile field .
The counter class also gives you a lock to
If I change the wait naotify to the following:
Counter.lock.notify();
Counter.lock.wait();
The code works. Dosen't wait() and notify() automatically takes the reference of the lock synchronize is on?
Producer Class
package multithreading;
public class CounterProducer implements Runnable {
public void run() {
try { incrCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void incrCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter < 1) {
System.out.println("Counter Reset");
Counter.counter = 10;
notify();
wait();
}
}
}
}
}
Consumer Class
package multithreading;
public class CounterConsumer implements Runnable {
public void run() {
try { consumeCounter(); } catch (InterruptedException e) { e.printStackTrace(); }
}
public void consumeCounter() throws InterruptedException {
while (true) {
synchronized (Counter.lock) {
if (Counter.counter > 0) {
System.out.println("Consumed");
Counter.counter--;
notify();
wait();
}
}
}
}
}
The Counter
public class Counter {
public static volatile int counter;
public static final Object lock = new Object();
}
The Counter
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
The Runner
public class CounterRunner {
public static void main(String[] args) {
Thread con = new Thread(new CounterConsumer());
Thread prod = new Thread(new CounterProducer());
con.start();
prod.start();
}
}
If I change the wait naotify to the following, the code works:
Counter.lock.notify();
Counter.lock.wait();
Every Java method is either a static method of some class or an instance method of some object. If you see a method call that does not contain an explicit class name or object reference, then it is an implicit call to a method belonging to the this object.
That is to say, notify() means the same thing as this.notify(), and wait() means this.wait().
this, refers to the CounterProducer instance when it appears in your CounterProducer.incrCounter() method, and it refers to the CounterConsumer instance when it appears in your CounterConsumer.consumeCounter() method.
Is there a way to enforce only a single execution of a thread object?
Something like a thread singleton?
To illustrate, consider below example:
I have a runnable implemented class.
I would like that I will be able to call start() method only one time of the object.
You can put a boolean as attribute to check if the thread has already been launch
Add a static boolean field in your Runnable and check it at the start of the run method like this:
synchronized(MyRunnable.class) {
if(alreadyRan) {
return;
}
alreadyRan = true;
}
Well, with the tips of my friends here in this thread, I reached the following:
public class TestThread extends Thread {
static private TestThread _instance = null;
private TestThread() {}
public static TestThread getThread(){
if(_instance == null)
_instance = new TestThread();
return _instance;
}
#Override
public void run()
{
System.out.println("Hello");
}
}
And this is an example of using it, when calling start for the second time throws an exception:
public class Main {
public static void main(String[] args) {
try {
TestThread.getThread().start();
TestThread.getThread().start();
} catch (IllegalThreadStateException e) {
System.out.println("Error: Tried to start more than one instance of this thread!");
e.printStackTrace();
}
}
}
Your comments are welcomed.
This question already has answers here:
Program hangs if thread is created in static initializer block
(4 answers)
Closed 8 years ago.
Can someone explain to me why the following code prints nothing?
When I tried to debug it, the debugger froze on the line t.join();. But in the debugger I saw the message: "program is running".
public class Main_problem1_multithreading {
private static boolean initialized = false;
static {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
initialized = true;
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
throw new AssertionError(e);
}
}
public static void main(String[] args) {
System.out.println(initialized);
}
}
Static initialization takes place when JVM loads a class first time. The thread that loads the class has a lock on Static Initializer , In this case main thread is already holding the lock.
Until that lock is released the newly spawned thread cannot access "initialized" variable.
You can clearly see in the image I attached. Thread - 0 is stepping at line 10. Line 10 is where new thread tries to update initialized variable. So this new thread keep waiting for the lock which it never gets and main thread keeps waiting for new thread to join it. Deadlock!! Hope it helps!
package com.test;
public class Test {
private static boolean initialized = false;
static {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
initialized = true;
System.out.println("New Thread" + initialized);
}
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.println("Main Thread" + initialized);
}
}
I can't figure out what is the problem in the following code:
I have a thread that can be suspended and resumed
Code bellow:
public class CustomThread implements Runnable {
private volatile boolean stop;
private volatile boolean suspend;
String[] names = new String[]{
"A", "B","C","D","E", "F", "G","H","I","J","K", "L"
};
public CustomThread(){
Collections.shuffle(Arrays.asList(names));
System.out.println("Available names:");
System.out.println(Arrays.asList(names));
}
#Override
public void run() {
while(!stop){
synchronized (this) {
if(suspend){
try {
System.out.println("Got suspended");
wait();
System.out.println("Resumed");
} catch (InterruptedException e) {
System.out.println("Got interupted");
}
}
else System.out.println("Suspend false");
}
int randomIdx = new Random().nextInt(names.length);
System.out.println(names[randomIdx]);
}
}
public synchronized void suspend(){
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>Suspend true");
suspend = true;
}
public synchronized void resume(){
suspend = false;
notify();
}
}
I run the following simple code:
public class CustomTest {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
CustomThread c = new CustomThread();
Thread t = new Thread(c);
t.start();
Thread.sleep(5000);
System.out.println("++++++++++++++++++++++++++++++++");
c.suspend();
}
}
What I am expecting to see is:
Thread custom runs, main sleeps, main suspends the custom thread by c.suspend() and since main terminates and noone resumes the thread, the thread remains in wait state.
But what I see instead is that the CustomThread prints continually Suspend false and an element from names.
What is the problem here? It is like the Thread.sleep(5000) and c.suspend() in main don't do anything.
The code is fine as written, but your problem is probably that you are running this through Eclipse and you are overwhelming the console. Put a shorter delay in main and you'll see good results.
Note: your suspend method doesn't need to be synchronized as it only writes to a volatile variable.
Instead of if(suspend) you should have while(suspend), see the explanation in javadoc here: http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#wait%28%29
From the javadoc of Object.wait():
...interrupts and spurious wakeups are
possible, and this method should always be used in a loop