-1

以下のコードでは、メソッドを同期するかどうかにかかわらず、出力に違いはありませbarん-何が間違っているのですか?「bar」を同期すると「ThreaOne」が10回印刷され、「ThreadTwo」の印刷のみが開始されると思いますが、そうではありません。私が得る出力は次のとおりです。


私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッドOneOneOneOne
私は今メインにいます
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッドOneOneOneOne
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッド2
私はテストスレッドです:スレッド2
私は今メインにいます

等々。これが私のコードです:

package com.rahul;

class ThreadTest implements Runnable{
    @Override
    public void run() {
        bar();
    }
    public synchronized void bar() {
        for(int i=0;i<10;i++){
            System.out.println("I am Test thread:"+Thread.currentThread().getName());
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    }
}

public class Test{
    public static void main(String[] args) {
        Thread t1 = new Thread(new ThreadTest(),"Thread OneOneOneOne");
        Thread t2 = new Thread(new ThreadTest(),"Thread Two");
        t1.start();
        try{
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        t2.start();
        while(true){
            System.out.println("I am in main now");
            try {
                t2.join();
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
4

3 に答える 3

3

の2つのインスタンスがありますThreadTest。彼らはお互いに何の関係もありません。あなたは同じことを呼んでいないbar()

代わりにこれを行う場合:

ThreadTest tt = new ThreadTest();
Thread t1 = new Thread(tt,"Thread OneOneOneOne");
Thread t2 = new Thread(tt,"Thread Two");

次に、2つのスレッドがのインスタンスを共有し、その単一のインスタンスで一度にThreadTest呼び出すことができるのは1つのスレッドのみです。bar()

于 2013-02-24T05:51:09.397 に答える
2

メソッドを宣言して synchronizedも、期待した効果は得られません。各スレッドはの独自のインスタンスで同期されるThreadTestため、呼び出しは相互作用しません。あるスレッドが別のスレッドをブロックするには、共有オブジェクトで同期する必要があります。例えば:

class ThreadTest implements Runnable{
    private static Object LOCK_OBJECT = new Object();
    @Override
    public void run() {
        bar();
    }
    public void bar() {
        synchronized (LOCK_OBJECT) {
            for(int i=0;i<10;i++){
                System.out.println("I am Test thread:"+Thread.currentThread().getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}
于 2013-02-24T05:52:31.550 に答える
0

同期しているメソッドはインスタンスメソッドであるため、1つのスレッドのみがアクセスしているため、各スレッドは独自のbarメソッドを呼び出しています。

たぶん、barメソッドをとして宣言したいと思うでしょうstatic

于 2013-02-24T05:52:53.200 に答える