Java:线程不起作用

时间:2014-05-23 12:13:38

标签: java multithreading

我正在尝试在for循环中启动一个线程。此任务应该只等待一秒钟(Thread.sleep()),因此每次循环重新开始时,都会启动一个新线程,它应该导致线程之后的代码等待它执行。

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)
       {
       }
   }
}

如您所见,我在两个方法System.out.println()中实现了它们是否实际执行。我明白了:

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

所以它应该是29,Timer,28,Timer等,但事实并非如此。 有谁知道代码有什么问题? 非常感谢。

8 个答案:

答案 0 :(得分:7)

启动线程的主循环可能主导CPU,因此它完成整个循环,然后线程才有机会去。

事实上,假设您的所有线程都睡了整整一秒而且您只循环了29次,那么您可以确保您的循环在您的线程之前完成(并打印所有数字)做。如果你想要打印线程,请在主循环中添加一个休眠 - 记住,当你启动一个线程时,主循环不会停止。

答案 1 :(得分:3)

你可以将一个线程加入主线程,所以首先你的线程将完成主线程

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);
    }
}

这是我生成2个线程或一个线程的代码取决于arrayList大小,但在我的情况下,这个线程执行更复杂的任务,然后等待1秒

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();
              }

在我的代码中,我使用实现Runnable接口的对象填充arrayList。

答案 2 :(得分:2)

即使您将线程休眠1ms,您的结果也会相同。如果您可以将线程管理的时间少于打印结果所需的时间,则结果可能与预期的一样。这是我的代码,我把时间设为1毫秒,但结果是一样的。

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);
        }
     }
}

如果您注释掉Thread.sleep(1)方法,那么结果就像您预期的那样。

答案 3 :(得分:0)

延迟足以让count()中的for循环完成之前可以打印&#39; timer&#39;来自线程。

答案 4 :(得分:0)

发生的事情是您启动的线程开始执行并立即进入休眠状态。与此同时,你的循环一直在运行。由于线程的整个点是它们异步运行,我真的不明白为什么你认为你的主循环应该等待它完成睡眠。线程已经开始运行,现在独立于主循环运行。

如果你想等待刚刚开始完成的线程(在这种情况下,你也可以使用一种方法),然后使用其中一个同步原语,即Thread.wait()

答案 5 :(得分:0)

您真正想要做的是在另一个线程运行时阻止您的主线程。请不要使用Thread#sleep语句,因为这些语句不可靠以“使您的应用程序正常工作”。你想要使用的是Thread#join。请参阅dharr他的代码示例。

此外,在创建线程或运行异步任务时最好使用ExecutorsExecutorServices

答案 6 :(得分:0)

线程很有趣。将虚拟线程视为物理线程。你穿的衣服上有许多线,所有衣服都在同时将你的衬衫固定在一起。在虚拟术语中,Thread.start()所做的是在不同的链上开始一个线程 WHILE 以下代码继续执行,(即两个线程同时工作,就像两个跑步者彼此相邻地运行一样)。考虑在Thread.start()之后立即设置一个断点。你明白了。

为了获得理想的效果,只需在主循环中放置Thread.sleep()即可。这将导致输出

29
Timer
28
Timer
// etc.

希望这会有所帮助。

贾罗德。

答案 7 :(得分:0)

衬衫中的线程的另一个类比:

将线程视为主程序的同事(这是一个线程本身)。如果你开始一个线程,你就给这个同事交一些工作。这位同事回到他的办公室来完成这项任务。你也继续做你的任务。

这就是为什么数字会出现在第一个线程/同事输出anythig之前。在他完成任务之前,你完成了任务(将工作分发给其他同事)。

如果您想要完成一些工作然后等待它完成,请按照其他人的建议使用t1.join()。但是如果你这样做,那么创建新的线程是没有道理的,因为你(似乎)并不想(和许多同事)并行处理某些东西,而是按照特定的顺序 - 你可以自己去做。