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

カウント: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();
        }
    }
}
4

3 に答える 3

1

「Count:5」が「EndingMain」の後にある理由は何ですか?

スレッドが開始されると、すぐに実行が開始される保証はありません。新しいスレッドが初期化されるときに、新しいスレッドをフォークしたスレッドが実行を継続するのは正常です。System.out.println("Ending Main");したがって、メインスレッドが5番目のスレッドを開始した後も、メインスレッドは実行を継続し、ステートメントにスレッドを打ち負かします。

スレッドの全体的なポイントは、スレッドが非同期的に実行されることであるということを理解することが重要です。スレッドは同時に実行されている別々のCPU/コアでスケジュールできるため、スレッドプログラムでの操作の順序を予測するのは非常に難しいことがよくあります。例えば。スレッドの競合状態が原因で、「カウント1」の前に「カウント2」が印刷される場合もあります。500スレッドから実行して実行したところ、次のようになりました。

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

また、はクラスに対してbankLockローカルであるため、スレッド間でNumberTaskロックされません。ロックを静的にして、クラスごとに1つのロックを設定することも、mainでロックをインスタンス化して、コンストラクターに渡すこともできます。はオブジェクトであるため、ここでは実際にロックは必要ありません。同じことがメソッドにも当てはまります。インスタンスで同期するため、同じオブジェクトで他のスレッドが同期しないため、何も実行されません。NumberTaskNumberTaskSystem.outPrintStramsynchronizedsynchronized run()NumberTask

于 2012-10-07T13:54:41.157 に答える
0

Execution of threads is not predictable, so you get this behavior. Use join() method to make one thread's execution to the end of another thread's execution.

Kindly read Java thread unpredictable

于 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 に答える