1

Javaスレッデッドコードがあります。私は3つのスレッドを持っており、それらすべてに名前を付けています。2つのコンシューマスレッド名Consumer1Consumer2。。という名前のプロデューサースレッドProducer。スレッドの名前を比較しようとする同期メソッドがあります。スレッド名がconsumer2の場合、しばらくスリープさせたいです。そのようです:

public synchronized String getReferer()
    {
        try{
            String threadName = Thread.currentThread().getName();
            System.out.println("Thread name: "+threadName);
            System.out.println(" compatre"+threadName=="Consumer2");
            if(threadName == "Consumer2"){
                System.out.println("It is consumer2. ...wait, you #$%^!!!");
                //this.wait();
            }
        }catch(Exception e){
            this.displayAndExit(e);
        }
        String line = "";
        int i = 0;
        try{
            finished = 0;
            if(this.hostnames2.isEmpty()){
                line = null;
            }else{
                line = this.hostnames2.take();
            }
        }catch(Exception e){
            this.displayAndExit(e);
        }
        return line;
    }
}

私はすべてのスレッドを次々に開始します。最初のプロデューサーとコンシューマーです。Consumer1何が起こるかというと、私が見ることができるthreadNameをあちこちにすすりConsumer2ます。しかし、2番目のsopで私はこのようなものを見ます!!!

スレッド名:Consumer2 false

これで、メソッドが同期されるため、スレッドは、メソッドが入るときにロックを保持します。では、Consumer2の場合、両方のステートメントが連続しているのに、文字列「Consumer2」との比較が失敗するのはなぜですか?

これがメインのメソッドであり、スレッドの呼び出しです。

public class OffensiveFilterApplicator 
{
    public static void main(String [] args)
    {
        String pathToCSV = "src/unique_referer_dump3.txt";
        CSVResourceHandler csvResHandler = new CSVResourceHandler(pathToCSV);
        HostnameFileData hfd = new HostnameFileData();
        HostnameReader hr = new HostnameReader(hfd, csvResHandler.getCSVFileHandler());
        VexigoCallOps vco = new VexigoCallOps(hfd);
        Thread producer = new Thread(hr);
        Thread consumer1 = new Thread(vco);
        Thread consumer2 = new Thread(vco);
        producer.setName("Producer");
        producer.start();
        consumer1.setName("Consumer1");
        consumer2.setName("Consumer2");
        consumer1.start();
        consumer2.start();
    }
}
4

2 に答える 2

17

を使用して文字列を比較することはできません==。を使用する必要がありますequals

詳細については 、「。equals」と「==」の違いは何ですか?をご覧ください。

于 2012-06-28T10:38:34.193 に答える
0

スレッドは、スレッドの名前の文字列を格納しません。名前が保存されるchar[]ので、呼び出すgetName()たびに実際には別のオブジェクトが取得されます。

Thread t = Thread.currentThread();
for (int i = 0; i < 10; i++)
    System.out.println(Integer.toHexString(System.identityHashCode(t.getName())));

次のようなものを印刷します

4318f375
1b17a8bd
2e471e30
3f0ef90c
7000a32b
39d8957f
3a3ee284
768965fb
36867e89
37dd7056

なぜそれは私が知らないStringで与えられたものを保存setNameしないのですか。私は歴史的な理由でそれを仮定します。

于 2012-06-28T10:56:25.360 に答える