繁体   English   中英

Java:线程不起作用

[英]Java: Thread doesn't work

我正在尝试在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等,但事实并非如此。 有人知道代码有什么问题吗? 非常感谢。

您正在启动线程的主循环可能会占据CPU的主导地位,因此它完成了整个循环,然后线程才有机会离开。

实际上,考虑到所有线程都睡了一秒钟,而您只循环了29次,因此可以确保循环将在线程执行之前完成(并打印所有数字)。 如果要打印线程,请在主循环中添加睡眠-请记住,启动线程时主循环不会停止。

您可以将一个线程加入主线程,这样您的线程将先完成,然后再进入主线程

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。

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

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)方法,则结果将与预期的一样。

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

发生的事情是,您启动的线程开始执行并立即进入睡眠状态。 同时,您的循环不断运行。 因为线程的全部要点是它们异步运行,所以我不太了解为什么您认为您的主循环应该等待它完成睡眠。 该线程已开始运行,并且现在独立于主循环运行。

如果要等待刚开始完成的线程(在这种情况下,您也可以使用一种方法),请使用同步原语之一,即Thread.wait()

您实际要做的是在另一个线程运行时阻塞您的主线程。 请不要使用Thread#sleep语句,因为它们不可靠,无法“使您的应用程序正常工作”。 您要使用的是Thread#join。 有关示例,请参见dharr的代码。

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

线程很有趣。 将虚拟线程视为物理线程。 您穿的衣服上有很多线,所有线都同时工作以将衬衫固定在一起。 在虚拟方面有什么Thread.start()的作用是启动一个线程在不同的链,而下面的代码继续执行(即两个线程同时工作,像2名选手下次运行到对方)。 考虑在Thread.start()之后放置一个断点。 你会明白的。

为了达到理想的效果,只需将Thread.sleep()放入主循环即可。 这将导致输出

29
Timer
28
Timer
// etc.

希望这会有所帮助。

Jarod。

另一个类似于衬衫中的线的类比:

将线程视为主程序的协作者(线程本身)。 如果启动线程,则将一些工作交给此同事。 该同事回到他的办公室从事这项工作。 您还将继续执行任务。

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

如果要分发一些工作然后等待完成,请按照其他人的建议使用t1.join()。 但是,如果执行此操作,则创建新的线程是没有意义的,因为您(似乎)不想(与许多同事)以特定的顺序并行处理某些事情-您可以自己进行处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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