Java:线程不';行不通

Java:线程不';行不通,java,multithreading,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 = Stri

我正在尝试在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,计时器,28,计时器等等,但它不是。 有人知道代码出了什么问题吗?
非常感谢。

启动线程的主循环很可能控制着CPU,因此它完成了整个循环,只有到那时线程才有机会运行


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

启动线程的主循环很可能控制CPU,因此它完成了整个循环,只有这样,线程才有机会运行


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

延迟足以让for循环在count()中完成,然后is才能从线程打印“timer”。

延迟足以让for循环在count()中完成要在之前完成,可以从线程打印“timer”。

所发生的是,您启动的线程开始执行并立即进入睡眠状态。同时,你的循环还在继续。由于线程的全部要点是它们异步运行,我真的不明白为什么您认为主循环应该等待它完成睡眠。线程已经开始运行,现在独立于主循环运行


如果您想等待刚刚开始的线程完成(在这种情况下,您最好使用一种方法),那么请使用其中一种同步原语,即
thread.wait()

发生的情况是,您启动的线程开始执行并立即进入睡眠状态。同时,你的循环还在继续。由于线程的全部要点是它们异步运行,我真的不明白为什么您认为主循环应该等待它完成睡眠。线程已经开始运行,现在独立于主循环运行


如果您想等待刚刚开始的线程完成(在这种情况下,您最好使用一种方法),那么请使用其中一种同步原语,即
thread.wait()

您可以将线程连接到主线程,以便先完成线程,然后再完成主线程

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();
              }
for(int i=0;i1){
t1=新线程(array.get(i));
t2=新线程(array.get(i+1));
t1.start();
t2.start();
}
否则{
t2=新线程(array.get(i));
t2.start();
}
如果(t1!=null)
t1.join();
如果(t2!=null)
t2.连接();
}

在我的代码中,我用实现可运行接口的对象填充arrayList。

您可以将线程连接到主线程,这样首先您的线程将完成,然后是主线程

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();
              }
for(int i=0;i1){
t1=新线程(array.get(i));
t2=新线程(array.get(i+1));
t1.start();
t2.start();
}
否则{
t2=新线程(array.get(i));
t2.start();
}
如果(t1!=null)
t1.join();
如果(t2!=null)
t2.连接();
}

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

您实际想要做的是在另一个线程运行时阻塞主线程。请不要使用Thread#sleep语句,因为为了“让应用程序工作”,这些语句是不可靠的。您想要使用的是线程连接。有关示例,请参见dharr his代码


另外,最好在创建线程或运行异步任务时使用and。

实际上,您要做的是在另一个线程运行时阻塞主线程。请不要使用Thread#sleep语句,因为为了“让应用程序工作”,这些语句是不可靠的。您想要使用的是线程连接。有关示例,请参见dharr his代码


另外,在创建线程或运行异步任务时,最好使用和。

线程很有趣。将虚拟线程视为物理线程。你穿的衣服上有很多线,所有的线都在同一时间把你的衬衫固定在一起。实际上,
Thread.start()
所做的是在不同的线程串上启动一个线程,同时继续执行以下代码(即两个线程同时工作,就像两个运行线程并排运行一样)。考虑休息一下