Java 在循环中使用线程,如何在到达主程序末尾之前完成for循环?

Java 在循环中使用线程,如何在到达主程序末尾之前完成for循环?,java,multithreading,Java,Multithreading,我的预期产出是 Count : 1 Count : 2 Count : 3 Count : 4 Count : 5 我尝试过同步和锁定,但两者都不起作用。我接触 尾干管 比我完成循环还快。电流输出为: Starting Main Count : 1 Count : 2 Count : 3 Count : 4 Ending Main Count : 5 你知道为什么计数:5是在主音结束后吗?这是我的密码: public class Demo { public static void m

我的预期产出是

Count : 1
Count : 2
Count : 3
Count : 4
Count : 5
我尝试过同步和锁定,但两者都不起作用。我接触

尾干管

比我完成循环还快。电流输出为:

Starting Main
Count : 1
Count : 2
Count : 3
Count : 4
Ending Main
Count : 5
你知道为什么计数:5是在主音结束后吗?这是我的密码:

public class Demo {
    public static void main( String [] args ) {
        System.out.println( "Starting Main" ) ;
        for ( int i = 1 ; i <= 5 ; i++ ) {
            Thread numberThread = new Thread(new NumberTask(i)) ;
            numberThread.start() ;
        }
        System.out.println( "Ending Main" ) ; 
    }
}

class NumberTask implements Runnable {
    private Lock bankLock = new ReentrantLock();
    int count ;
    public NumberTask( int count ) {
        this.count = count ;
    }

    synchronized public void run() {
        bankLock.lock();
        try {
            System.out.println( "Count : " + count ) ;
        } finally {
            bankLock.unlock();
        }
    }
}
公共类演示{
公共静态void main(字符串[]args){
System.out.println(“启动主管道”);
对于(int i=1;i
知道为什么“Count:5”在“Ending Main”之后吗

当线程启动时,不能保证它立即开始运行。当新线程初始化时,分叉新线程的线程继续运行是正常的。因此,在主线程启动第5个线程后,它继续运行并将线程发送到
System.out.println(“Ending main”);
语句

重要的是要认识到线程的全部要点是它们以异步方式运行。因为线程可以在单独的CPU/内核上同时运行,所以通常很难预测线程程序中的操作顺序。例如,您也可能看到之前打印的“计数2”“计数1”只是因为。我刚开始运行500个线程,我看到:

Count : 128
Count : 130
Count : 129
Count : 131

另外,由于您的
bankLock
NumberTask
类的本地锁,因此它不会在线程之间锁定。您可以将锁设置为
NumberTask
的静态锁,使每个类都有一个锁,或者您可以在main中实例化锁并将其传递到
NumberTask
构造函数中。您真的不需要此处锁定,因为
系统.out
PrintStram
,它是
同步的
对象。这同样适用于
同步的
运行()
方法。由于您将在
NumberTask
实例上进行同步,因此它不会执行任何操作,因为没有其他线程将在同一对象上进行同步。

线程的执行是不可预测的,因此您会得到此行为。使用方法使一个线程的执行结束于另一个线程的执行

请阅读

您可以使用join()等待其他线程完成。您的代码需要更新如下:

public static void main( String [] args ) {

    System.out.println( "Starting Main" ) ;
        Thread numberThread;
        for ( int i = 1 ; i <= 5 ; i++ ) {
            numberThread = new Thread(new NumberTask(i)) ;
            numberThread.start() ;
        }
        numberThread.join();
        System.out.println( "Ending Main" ) ; 
    }
publicstaticvoidmain(字符串[]args){
System.out.println(“启动主管道”);
螺纹号读数;

对于(int i=1;我将“bankLock”定义为静态,但仍然无法获得恒定的输出。我使用lock的原因是我希望循环从1开始,按顺序从5开始。通过使用“join()解决了此问题)“。但是为什么锁不起作用我不知道。除非你使用大量的锁或使用单个线程,否则你永远不能保证它从1到5@Bernard。同样,正如我的回答所说,线程的整个点是异步和并发运行的。它不起作用,因为我认为numberThread.join();必须在循环内。无论如何,我还是想到了这个主意!由于连接在循环内,所以没有必要分叉任何线程@Bernard。您不妨从主线程调用
new NumberTask(I).run();
。您能解释一下为什么需要以特定方式输出吗?那么为什么要使用线程呢?