简体   繁体   中英

Java: Thread doesn't work

I'm trying to start a thread in a for-loop. This task should only wait for a second (Thread.sleep()), so every time the loop starts over again, a new thread is started and it should cause the code after the thread to wait until it is executed.

public void count()
{
    for(int i = 29; i>=0; i--)
    {
        Thread t1;
        t1 = new Thread(new TimerClass());
        t1.start();
        String s = String.valueOf(i); 
        jLabel6.setText(s);
        System.out.println(s);
    }
}


public class TimerClass implements Runnable{

   @Override
   public void run()
   {
       try{
           Thread.sleep(1000);
           System.out.println("Timer");
       } catch(InterruptedException e)
       {
       }
   }
}

As you can see, I implemented in both methods System.out.println() to check if they are actually executed. I get this:

29
28
27
26
...//25 - 3
2
1
0
Timer
Timer
Timer
//in all 29 times Timer

So it should be 29, Timer, 28, Timer and so on, but it isn't. Does anyone know what's wrong with the code? Thanks a lot.

Your main loop that is starting the thread is likely dominating the CPU, so it finishes doing its entire loop and only then do the threads get a chance to go.

In fact, given that all of your threads sleep for an entire second and you're only looping 29 times, you're guaranteed that your loop will finish (and print all of the numbers) before your threads do. Add a sleep to your main loop if you want the threads to print - remember, the main loop doesn't stop when you start a thread.

You can join a thread to the main thread so first your thread will finished then main thread

public void count()
{
    for(int i = 29; i>=0; i--)
    {
        Thread t1;
        t1 = new Thread(new TimerClass());
        t1.start();
        t1.join();
        String s = String.valueOf(i); 
        jLabel6.setText(s);
        System.out.println(s);
    }
}

Here is my code for spawning 2 threads or one thread depends on arrayList size but in my case this threads are doing much more complex tasks then just waiting 1 sec

for (int i = 0; i < array.size(); i += 2) {
            Thread t1 = null;
            Thread t2 = null;

            if (i < array.size() - 1 && array.size() > 1) {

                t1 = new Thread(array.get(i));
                t2 = new Thread(array.get(i + 1));
                t1.start();
                t2.start();

            }

            else {

                t2 = new Thread(array.get(i));

                t2.start();
            }
            if (t1 != null)
                t1.join();
            if (t2 != null)
                t2.join();
              }

In my code I populate arrayList with Objects that Implements Runnable interface.

Even if you sleep the thread for 1ms, your results would be the same. If you can manage the thread to sleep for the time less than it takes to print the results, your result could be as expected. Here is my code where I have put the time of 1 ms but yet the results are the same.

public class MultiThreading implements Runnable
{
       public void run()
       {
           try
           {
               Thread.sleep(1);
               System.out.println("Timer");
           } 
           catch(Exception e)
           {

           }
       }

    public static void main(String [] args)
    {
        for(int i = 29; i>=0; i--)
        {
            Thread t1;
            t1 = new Thread(new MultiThreading());
            t1.start();
            String s = String.valueOf(i); 
            System.out.println(s);
        }
     }
}

If you comment out the Thread.sleep(1) method, then your results are as you expected.

延迟足以让count()中的for循环在可以从线程打印“计时器”之前完成。

What is happening is that the thread you started starts executing and immediately goes to sleep. In the meantime, your loop just keeps running. As the whole point of threads is that they run asynchronously, I don't really understand why you think your main loop should be waiting for it to finish sleeping. The thread has started running and is now running independently of the main loop.

If you want to wait for the thread you just started to finish (in which case, you might as well use a method), then use one of the synchronisation primitives, ie Thread.wait() .

What you actually want to do is block your main thread while another thread is running. Please don't use Thread#sleep statements, as these are unreliable in order to "make your application work". What you want to use instead is Thread#join. See dharr his code for an example.

Also, it's better to use Executors and ExecutorServices when creating threads or running async tasks.

Threads are interesting. Think of a virtual thread as a physical thread. There are many threads on the clothes you're wearing, all working at the same time to hold your shirt together. In virtual terms what Thread.start() does is start a thread on a different strand WHILE the following code continues to execute, (ie Two Threads work simultaneously like 2 runners run next to each other). Consider putting a break point right after Thread.start() . You'll understand.

For your desired effect, just put a Thread.sleep() in the main loop. This will cause an output of

29
Timer
28
Timer
// etc.

Hope this helped.

Jarod.

Another analogy to the threads in a shirt:

Think of threads as coworkers to your main programm (which is a thread itself). If you start a thread, you hand some work to this coworker. This coworker goes back to his office to work on this task. You also continue to do your task.

This is why the numbers will appear before the first thread/coworker will output anythig. You finished your task (handing out work to other coworkers) before he finished his.

If you want to give out some work and then wait for it to be finished, use t1.join() as suggested by others. But if you do this, it is senseless to create new Threads, because you don't (seem) to want to process something in parallel (with many coworkers) but in a specific order - you can just du it yourself.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM