class myRunnable implements Runnable {
public void run() {
// TODO Auto-generated method stub
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
}
}
}
Result in the console:
main
main
main
main
...
main
main
main
main
I can't find any "run" word, this means the run method didn't run. Can somebody explain that for me. Thank you.
PS: when i<10, i<100, i<1000, i<10000, I can find the "run" word, but when i<100000 then I can't find the "run" word, that's just weird
Run has been printed out. But your console-buffer is not large enougth.
Change the Console-configuration to unlimited buffer.
First of all, Yes, Your code actually prints "run".
Just make this little change below and You´ll see it.
A more rigorous test, If You can see it in a different way, is to send the strings to a text file instead of the console. You will certanly find the word "run".
class myRunnable implements Runnable {
#Override
public void run() {
// TODO Auto-generated method stub
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Your implementation runs just fine. You just don't see your run message because there hasn't been any thread switch just yet.
The problem is that the action on which you examine the threads is too short. You can insert a Thread.sleep(2000); for example to check it out.
I find this wired that you can't find a run in your output, the thing is that you should understand how the java thread mechanism works, the main thread will not wait for the child thread to complete their work, unless you make it specific, thus whether or not the child complete before the main thread complete (and exit) is not expectancy.
if you do want the main thread to wait for the child thread to complete, you can make it specific by:
t.start();
t.join();
You should have to catch some exception to make this work.
But I think it should be high ratio that you should see a run printed in your original code. because it seems the main thread is more time consuming.
regardless of this, there is nothing to blame if your jvm behave like this. the thread executing order is not insured by the standard anyway.
Simply add a delay of one second within the loop as displayed below:
class myRunnable implements Runnable {
public void run() {
System.out.println("run");
}
}
public class TestThread {
public static void main(String[] args) {
Runnable threadJob = new myRunnable();
Thread t = new Thread(threadJob);
t.start();
for (int i = 0; i < 100000; i++) {
System.out.println("main");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Related
I had a very peculiar problem happening to me that I could not solved except splitting up the Problem into two classes.
I would like to know if there is maybe a solution without splitting the class and I would more importantly like to know if anybody has an idea why the Java Engine is deciding to act the way it does.
The Problem:
I have a class with a static method, a static field and a constructor. The static field is initialized to an instance of the class itself. During the instance initialization I want to access the aformentioned static method. See the following code:
public class Simple {
public Simple() {
int count = 4;
for (int i = 0; i < count; i++) {
System.out.println("Simple: " + Simple.isFlag());
}
}
private static Simple i = new Simple();
public static boolean isFlag() {
return true;
}
public static void run() {
}
}
public class Main {
public static void main(String[] args) {
Simple.run();
}
}
This code runs absolutely fine. The output can be seen below:
Simple: true
Simple: true
Simple: true
Simple: true
The output is generated after I call the run() method because the stativ field i is only initialized after I access the first static member of that class.
I now want to do the exact same thing except with multiple threads. See here:
public class Parallel {
public Parallel() {
int count = 4;
CountDownLatch latch = new CountDownLatch(4);
for (int i = 0; i < count; i++) {
Thread t = new Thread(() -> {
System.out.println("Parallel: " + Parallel.isFlag());
latch.countDown();
Thread.currentThread().interrupt();
});
t.start();
}
try {
latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static Parallel i = new Parallel();
public static boolean isFlag() {
return true;
}
public static void run() {
}
}
public class Main {
public static void main(String[] args) {
Parallel.run();
}
}
This returns nothing. The main thread is stuck at latch.await();, while the other threads are stuck at Parallel.isFlag(). Edit: as shown by Jaims below, the threads don't even start at all.
This does not make any sense to me. Why is this not working, but the first case is? Essentially they are doing the same.
I would like to know how the Java Engine decides on when to wait and when not. Can this be changed somewhere in code?
Additionally, this has nothing to do with CountDownLatch but solely with the multithreading. Look at this final sample:
public class NonParallel {
public NonParallel() {
int count = 4;
CountDownLatch latch = new CountDownLatch(4);
for (int i = 0; i < count; i++) {
System.out.println("NonParallel: " + NonParallel.isFlag());
latch.countDown();
}
try {
latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static NonParallel i = new NonParallel();
public static boolean isFlag() {
return true;
}
public static void run() {
}
}
public class Main {
public static void main(String[] args) {
NonParallel.run();
}
}
This works fine. The output is as following:
NonParallel: true
NonParallel: true
NonParallel: true
NonParallel: true
Edit: none of this applies when the object initlization is not part of the class initilization. This is purely about class initialization which only happens when using a static object as described in this question. See here:
public class NonStaticParallel {
public NonStaticParallel() {
int count = 4;
CountDownLatch latch = new CountDownLatch(4);
for (int i = 0; i < count; i++) {
Thread t = new Thread(() -> {
System.out.println("NonStaticParallel: " + isFlag());
latch.countDown();
});
t.start();
}
try {
latch.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean isFlag() {
return true;
}
public static void run() {
new NonStaticParallel();
}
}
This one works without any issue:
Parallel: true
Parallel: true
Parallel: true
Parallel: true
Answers:
Andreas provides an explanation as to what is going on.
Jaims is right in that the threads do not even start at all. This probably happens because they need the class to be initialized and they are immediately therefore blocked. (If we use runnables that are in their own classes instead of lambda or anonymous inner classes then they run normally, unless of course they acess the any static members of the class being initialized)
Yoshi provides a link and an excerpt from the the spec, and is therefore marked as the right answer, as this is what I wanted.
I tried your code and did two things:
First, I made the lambda a static inner class of Parallel ... just in case; this didn't change anything.
Since you commented that the threads are stuck on Parallel.isFlag() I tried replacing the call with just true... and it worked!
So, I did a little research and I found this, which sounds like a promising explanation for what is going on: http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2
Specifically this part:
For each class or interface C, there is a unique initialization lock LC. The mapping from C to LC is left to the discretion of the Java Virtual Machine implementation. The procedure for initializing C is then as follows:
Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC.
If the Class object for C indicates that initialization is in progress for C by some other thread, then release LC and block the current thread until informed that the in-progress initialization has completed, at which time repeat this step.
(Emphasis added.) So this would suggest the following:
Main thread started class initialization while evaluating private static Parallel i = new Parallel(); and started up the threads. Then it waited on latch.await(). Class object for Parallel should indicate that initialization is "in progress."
Started threads also try to reference a static member of Parallel. Each thread sees that initialization is in progress and decides to wait until the Main thread (which is now waiting on the threads to count down the latch) is done. Clearly this is a deadlock.
When you call run(), the current thread will begin class initialization. Any code referring to the class, e.g. call to isFlag() will also require class initialization.
In your Simple and NonParallel versions, the current thread is doing it all, and recursive class initialization is allowed (ignored actually), so isFlag() is executed, even though the class initialization is not yet complete.
In your Parallel version however, the call to isFlag() is done from another thread, and so that other thread has to wait for the class to be fully initialized. Since your constructor won't return until the threads run, and the threads can't run until the constructor returns and completes the class initialization, you have a deadlock.
Conclusion: You cannot perform class initialization code in parallel. Class initialization has to complete in a single thread.
You can start threads during class initialization if you want, but you cannot wait for them to complete (if they also access your class, and what would be the point of they didn't?).
Your threads are not started until the object is created correctly. Consider the following snippet:
public class Main {
public static void main(String[] args) {
Parallel.run();
}
}
class Parallel {
private static Parallel i = new Parallel();
public Parallel() {
try {
System.out.println("Inside constructor.");
for (int i = 0; i < 4; i++) {
Thread t = new Thread(() -> {
System.out.println("Running thread.");
});
System.out.println("Starting thread.");
t.start();
}
System.out.println("Sleeping 2 seconds.");
Thread.sleep(2000);
System.out.println("Leaving constructor.");
} catch (InterruptedException ex) {
Logger.getLogger(Parallel.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void run() {
}
}
It'll produce the following output:
Inside constructor.
Starting thread.
Starting thread.
Starting thread.
Starting thread.
Sleeping 2 seconds.
Leaving constructor.
Running thread.
Running thread.
Running thread.
Running thread.
The threads are started within the constructor 4 times, as the output shows. It starts sleeping for 2 seconds, leaves the constructor and then runs your threads. Not like it takes 2 seconds for your threads to run.
So the core issue with your problem, is that you're calling latch.await(), but your threads never get the chance to actually run. Meaning the latch isn't decremented and simply keeps waiting. You could move the logic to your run() method, but I'm not really sure what you're trying to achieve in the first place. e.g.
public static void run() {
int count = 4;
CountDownLatch latch = new CountDownLatch(4);
for (int i = 0; i < count; i++) {
Thread t = new Thread(() -> {
try {
Thread.sleep(2000);
latch.countDown();
} catch (InterruptedException ex) {
Logger.getLogger(Parallel.class.getName()).log(Level.SEVERE, null, ex);
}
});
System.out.println("Starting thread.");
t.start();
}
try {
System.out.println("Current count: " + latch.getCount());
latch.await();
System.out.println("Current count: " + latch.getCount());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have this code below, that evaluates if three threads are done, and if yes, it continues with the code. The problem is that when I include some sort of print statement before the if statement, it works as usual. However, when I don't include the print, it continues forever. Here it is:
while (!are_we_done) {
System.out.println(are_we_done);
if (thread_arr[0].are_we_done==true && thread_arr[1].are_we_done==true && thread_arr[2].are_we_done==true) {
are_we_done=true;
}
}
Any clue as to what's going on?
Thanks in advance for any help/advice.
The problem was that I had to specify the are_we_done variable in the thread class as volatile.
Your work with threads is awesome - google for 'busy waiting'.
in main thread introduce 'latch = new CountDownLatch(<number of threads>)' variable
pass it into all your threads
on finish of the thread call 'latch.countDown()'
in main thread wait for all spawned threads complete with 'latch.await(...)'
Example:
public static void main(String... args) throws Exception {
Thread[] threads = new Thread[3];
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new YourRunnable(latch));
threads[i].start();
}
while (!latch.await(1000)) {
System.out.println("Not complete yet");
}
System.out.println("Complete!");
}
public class YourRunndable implements Runnable {
... // fields + constructor
public void run() {
try {
... // do your staff
} finally {
latch.countDown();
}
}
}
public class TestSynchronization {
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(Thread th : threads) {
th = new Thread(Integer.toString(i++));
th.start();
}
}
class ThreadTest extends Thread {
TestSynchronization ts = new TestSynchronization();
public /*synchronized */void run() {
synchronized(this) {
ts.testingOneThreadEntry(this);
System.out.println(new Date());
System.out.println("Hey! I just came out and it was fun... ");
this.notify();
}
}
}
private synchronized void testingOneThreadEntry(Thread threadInside) {
System.out.println(threadInside.getName() + " is in");
System.out.println("Hey! I am inside and I am enjoying");
try {
threadInside.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I am not able to start the ThreadTest instances.
I expect that ThreadTest's run method be executed as soon as the line th.start(); is executed, the one inside main method.
When I run the program, I see niether my system.out nor any exception.
I debugged also, but could see loop runs 10 times.
You just started a Thread, not a ThreadTest. Thread's run() method does nothing. Instead, create and start() a ThreadTest.
for(ThreadTest th : threads) {
th = new ThreadTest(Integer.toString(i++));
th.start();
}
You'll also need a one-arg constructor in your ThreadTest class that will take the String you're passing to it.
public ThreadTest(String msg){
super(msg);
}
You'll also need to make the ThreadTest class static so you can access that nested class from the static main method.
static class ThreadTest extends Thread {
However, you'll wind up will all Threads waiting. As written, this code will call wait inside every Thread, but it will never get to notify. The notify method must be called on the Thread to be notified, from another Thread. If it's waiting, then it can never notify itself.
You have array of ThreadTest (thread) class which is not used.
I assume you wanted this:
public static void main(String[] args) {
ThreadTest[] threads = new ThreadTest[10];
int i = 0;
for(int i=0;i<threads.length;i++) {
threads[i] = new ThreadTest();
threads[i].start();
}
}
I have a static function like:
public static void foo()
{
//code follows
System.out.println(Thread.currentThread().getName());
//code follows
}
and multiple threads are calling this function concurrently. I have set the names of threads using
Thread.setName(String)
When i execute the code, the print statement will print the name of only one thread. How can i identify the names of all the threads currently executing the foo() function?
EDIT:
public class FooThread extends Thread
{
public FooThread(String name)
{
this.setName(name);
}
#Override public void run()
{
//do something
//do something
Main.foo();
}
}
//Main Class
public class Main
{
public static void main(String[] args)
{
for(int i=0;i<6;++i)
{
new FooThread("Thread"+i).start();
}
}
public static void foo()
{
//do something
while(true)
{
//do something
System.out.println(Thread.currentThread().getName());
}
}
}
You're already showing the name of the Thread that is calling your code. Code that proves this:
public class Foo2 {
public static synchronized void foo() {
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args) {
int maxCount = 10;
for (int i = 0; i < maxCount; i++) {
Thread thread = new Thread(new Runnable() {
public void run() {
foo();
}
});
thread.setName("Thread " + i);
thread.start();
long sleepTime = 1000;;
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
}
}
Return:
Thread 0
Thread 1
Thread 2
Thread 3
Thread 4
Thread 5
Thread 6
Thread 7
Thread 8
Thread 9
Your problem lies in code not shown.
Either your method is being called by one and only one thread, or
Or you're giving all your threads the same name.
Again, for a complete solution as to what is actually wrong with your current set up, create and post an sscce similar to what I've posted above. For all we know you could be calling run() on your Threads, and until we can see and reproduce your problem, I don't think that we'll be able to fully understand it.
EDIT
Regarding your SSCCE: Compare the results of the two methods below, foo1() and foo2()
class FooThread extends Thread {
public FooThread(String name) {
this.setName(name);
}
#Override
public void run() {
// do something
// do something
Main.foo1(); // !! Swap comments
// Main.foo2(); // !! Swap comments
}
}
// Main Class
public class Main {
private static final long SLEEP_TIME = 4;
public static void main(String[] args) {
for (int i = 0; i < 6; ++i) {
new FooThread("Thread" + i).start();
}
}
public static void foo1() {
// do something
while (true) {
// do something
synchronized (Main.class) {
System.out.println(Thread.currentThread().getName());
}
try {
Thread.sleep(SLEEP_TIME);
} catch (InterruptedException e) {}
}
}
public static void foo2() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
}
If your while loop isn't so tight, but yields the CPU with say a short Thread.sleep, you'll see more of the different threads sharing foo in closer proximity.
But again, your code also proves that your Thread names *are8 being displayed, but that you're only seeing one name likely because that thread is hogging the CPU.
Another option is to get all the Thread stacks and look for all the threads in the foo() This has the benefit of no overhead or extra code, except to capture the information you want.
BTW: Can you make it clearer why do you need this information as I suspect there is a better way to do what you really want?
If you only want to get the count of threads, use a thread-safe counter to store number of threads. Increase the counter when foo() begins, and decrease the counter when foo() exits.
If you need to get the names, use a hash set (or list if there are duplicates of thread names) to store the names: Add the name when foo() begins, and remove the name when foo() exits. Make sure the access to hash set is thread safe. You also need another method to print out the content of the hash set, so you can call it any time to see what are the name of threads executing foo().
You can put the name into a list when the method starts (in a synchronized block) and remove it at the end again.
List allTheNames = Collections.synchronizedList(new ArrayList<String>());
public void foo() {
allTheNames.add(Thread.currentThread().getName());
// now allTheNames contains all the names of all threads currently in this method.
System.out.println(allTheNames.toString());
allTheNames.remove(Thread.currentThread().getName());
}
Of course, if you change the name of the thread in the meantime that wont work, but why would you do so?
You could also store the Thread itself if you need other informations that the name.
Not sure sure if I am doing this right. I need to make a new thread to write out message certain number of times. I think this works so far but not sure if its the best way of doing it. Then i need to display another message after thread has finished running. How do I do that ? Using isAlive() ? How do i implement that ?
public class MyThread extends Thread {
public void run() {
int i = 0;
while (i < 10) {
System.out.println("hi");
i++;
}
}
public static void main(String[] args) {
String n = Thread.currentThread().getName();
System.out.println(n);
Thread t = new MyThread();
t.start();
}
}
Till now you are on track. Now, to display another message, when this thread has finished, you can invoke Thread#join on this thread from your main thread. You would also need to handle InterruptedException, when you use t.join method.
Then your main thread will continue, when your thread t has finished. So, continue your main thread like this: -
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Your Message");
When your call t.join in a particular thread (here, main thread), then that thread will continue its further execution, only when the thread t has completed its execution.
Extending the Thread class itself is generally not a good practice.
You should create an implementation of the Runnable interface as follows:
public class MyRunnable implements Runnable {
public void run() {
//your code here
}
}
And pass an intance of it to the thread as follows:
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
Please check this answer here on SO: Implementing Runnable vs. extending Thread
This is how you can do that.........
class A implements Runnable
{
public void run()
{
for(int i=1;i<=10;i++)
System.out.println(Thread.currentThread().getName()+"\t"+i+" hi");
}
}
class join1
{
public static void main(String args[])throws Exception
{
A a=new A();
Thread t1=new Thread(a,"abhi");
t1.start();
t1.join();
System.out.println("hello this is me");//the message u want to display
}
}
see join() details on
join