Thread.getName显示异常:执行put/get时线程名仍为main而非自定义名称
问题原因分析
你遇到的线程名称显示错误的核心原因是Q类中Thread对象的初始化时机错误:
- Q类里的
Thread t = Thread.currentThread();是在Q实例创建时(Main线程执行new Q())初始化的,此时currentThread()返回的是main线程,所以t变量被固定指向了main线程。 - 后续Producer和Consumer线程调用put/get方法时,始终使用这个提前绑定的main线程对象来获取名称,自然输出的都是
main thread。
解决方案
删除Q类中提前缓存的t变量,在需要获取当前线程名称的地方,直接调用Thread.currentThread().getName(),这样每次调用方法时,都会获取到正在执行该方法的实际线程的名称。
修改后的Q类核心代码如下:
public class Q { boolean ready = false; List<Integer> products; Q(){ products = new ArrayList<>(5); } synchronized void put(int n){ while (ready){ try { wait(); } catch (InterruptedException e){ System.out.println(Thread.currentThread().getName() + " was interrupted!"); System.out.println(); System.out.println(e); } } if(products.size() < 5){ this.products.add(n); System.out.println(Thread.currentThread().getName() + " thread, Put: " + n); ready = true; notify(); } else { System.out.println(Thread.currentThread().getName() + " thread, List is full!"); ready = true; notify(); } } synchronized List<Integer> get(){ while (!ready){ try { wait(); } catch (InterruptedException e){ System.out.println(Thread.currentThread().getName() + " thread was interrupted!"); System.out.println(); System.out.println(e); } } if(products.size() > 1){ System.out.println(Thread.currentThread().getName() + " thread, Got: " + products); System.out.println(Thread.currentThread().getName() + " thread, Consumed: \"" + (products.get(products.size() - 1)) + "\""); removeLastElement(); ready = false; notify(); } else { System.out.println(Thread.currentThread().getName() + " thread, List is empty!"); ready = false; notify(); } return products; } void removeLastElement(){ int index = (this.products.size() - 1); this.products.remove(index); } }
验证说明
修改后,当Producer1线程调用queue.put()时,Thread.currentThread()会返回Producer1线程对象,输出对应的名称;Consumer1线程调用queue.get()时同理,就能得到你预期的输出结果。
内容的提问来源于stack exchange,提问作者OrlandoVSilva
相关产品推荐
相关产品推荐

