0

我的预期输出是

Count : 1
Count : 2
Count : 3
Count : 4
Count : 5

我尝试过同步和锁定,但它们都不起作用。我到达

结束主要

在我完全完成循环之前。当前输出为:

Starting Main
Count : 1
Count : 2
Count : 3
Count : 4
Ending Main
Count : 5

知道为什么 Count : 5 在 Ending Main 之后吗?这是我的代码:

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

3 回答 3

1

知道为什么“计数:5”在“结束主要”之后吗?

当一个线程启动时,不能保证它立即开始运行。派生新线程的线程在新线程初始化时继续运行是正常的。所以,在主线程启动第 5 个线程后,它继续运行并击败线程到System.out.println("Ending Main");语句。

重要的是要意识到线程的全部意义在于它们以异步方式运行。因为线程可以在不同的 CPU/内核上调度并发运行,所以通常很难预测线程程序中的操作顺序。例如。由于线程竞争条件,您也可能会在“Count 1”之前看到“Count 2”打印。我刚从 500 个线程开始运行它,我看到:

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

此外,由于您bankLock是类的本地对象NumberTask,因此它不会在线程之间锁定。您可以将锁设为静态以使每个类NumberTask有一个锁,或者您可以在 main 中实例化锁并将其传递给构造函数。你真的不需要这里的锁,因为它是一个对象。方法也是如此。由于您将在实例上同步,因此它不会做任何事情,因为没有其他线程将在同一个对象上同步。NumberTaskSystem.outPrintStramsynchronizedsynchronized run()NumberTask

于 2012-10-07T13:54:41.157 回答
0

线程的执行是不可预测的,所以你会得到这种行为。使用join()方法使一个线程的执行到另一个线程的执行结束。

请阅读Java线程不可预知

于 2012-10-07T14:07:56.513 回答
0

您可以使用 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" ) ; 
    }
于 2012-10-07T14:09:12.363 回答