我有一个java线程代码。我有3个帖子,我已经为所有人提供了名字。 2个消费者主题名称为Consumer1
和Consumer2
。名为Producer
的生产者线程。我有一个synchronized方法,我尝试比较线程的名称。我希望如果线程名称是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;
}
}
我一个接一个地启动所有线程,第一个生产者和消费者。如果我s.o.p threadName我可以看到Consumer1
和Consumer2
到处都是。但是在第二个s.o.p我看到这样的东西!!!
主题名称:Consumer2 假的
现在,由于方法是同步的,因此线程在进入时会锁定它。因此,如果它是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();
}
}
答案 0 :(得分:17)
您无法使用==
比较字符串。您必须使用equals
。
答案 1 :(得分: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
。我认为这是出于历史原因。