首页 > 解决方案 > "ClassName::new" VS "new ClassName()" in JAVA

问题描述

there are my code:

public class UserThreadFactory implements ThreadFactory {
  private final String namePrefix;
  private final AtomicInteger nextId = new AtomicInteger(1);

  public UserThreadFactory(String whatFeatureOfGroup) {
    this.namePrefix = "From User ThreadFactory's " + whatFeatureOfGroup + "-Worker-";
  }

  @Override
  public Thread newThread(@NotNull Runnable r) {
    String name = namePrefix + nextId.getAndIncrement();
    Thread thread = new Thread(null, r, name, 0, false);
    System.out.println("Thread Name:" + thread.getName() + "\n HashCode:" + r.hashCode());
    return thread;
  }
public class MyRunnableThread implements Runnable {

  public MyRunnableThread() {
    System.out.println("The constructor is called");
  }

  @Override
  public void run() {
    String name = Thread.currentThread().getName();
    try {
      Thread.sleep(100);
      System.out.println(name + hashCode());
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }

}
public class CreateThreadByThreadFactory {
  public static void main(String[] args) {
    UserThreadFactory factory = new UserThreadFactory("localHost");
    Thread thread;
    for (int i = 0; i < 20; i++) {
      thread = factory.newThread(new MyRunnableThread());//FIRST WAY
      thread = factory.newThread(() -> new MyRunnableThread());//SECOND WAY
      thread.start();
    }
  }
}

When I use the first way to create some therad in class CreateThreadByThreadFactory, I created twenty threads, each with its own MyRunnableThread object. But, when I use the second way to create therads, i find that the hashCode of their MyRunableThread object is the same in all threads, and the constructor of the MyRunnableThread is only called once.Why?Can anyone explain what happend?

The follow code is the console printing in two ways

FIRST WAY:

The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-1
 HashCode:1996181658
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-2
 HashCode:806353501
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-3
 HashCode:521645586
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-4
 HashCode:1296064247
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-5
 HashCode:1637070917
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-6
 HashCode:780237624
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-7
 HashCode:205797316
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-8
 HashCode:1128032093
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-9
 HashCode:1066516207
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-10
 HashCode:443308702
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-11
 HashCode:935044096
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-12
 HashCode:396180261
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-13
 HashCode:625576447
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-14
 HashCode:1560911714
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-15
 HashCode:939047783
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-16
 HashCode:1237514926
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-17
 HashCode:548246552
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-18
 HashCode:835648992
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-19
 HashCode:1134517053
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-20
 HashCode:492228202
From User ThreadFactory's localHost-Worker-161237514926
From User ThreadFactory's localHost-Worker-17548246552
From User ThreadFactory's localHost-Worker-15939047783
From User ThreadFactory's localHost-Worker-11935044096
From User ThreadFactory's localHost-Worker-10443308702
From User ThreadFactory's localHost-Worker-91066516207
From User ThreadFactory's localHost-Worker-51637070917
From User ThreadFactory's localHost-Worker-41296064247
From User ThreadFactory's localHost-Worker-3521645586
From User ThreadFactory's localHost-Worker-20492228202
From User ThreadFactory's localHost-Worker-18835648992
From User ThreadFactory's localHost-Worker-191134517053
From User ThreadFactory's localHost-Worker-141560911714
From User ThreadFactory's localHost-Worker-6780237624
From User ThreadFactory's localHost-Worker-7205797316
From User ThreadFactory's localHost-Worker-81128032093
From User ThreadFactory's localHost-Worker-12396180261
From User ThreadFactory's localHost-Worker-13625576447
From User ThreadFactory's localHost-Worker-2806353501
From User ThreadFactory's localHost-Worker-11996181658

Process finished with exit code 0
SECOND WAY:

Thread Name:From User ThreadFactory's localHost-Worker-1
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-2
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-3
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-4
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-5
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-6
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-7
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-8
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-9
 HashCode:1996181658
The constructor is called
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-10
 HashCode:1996181658
The constructor is called
The constructor is called
The constructor is called
The constructor is called
The constructor is called
The constructor is called
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-11
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-12
 HashCode:1996181658
The constructor is called
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-13
 HashCode:1996181658
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-14
 HashCode:1996181658
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-15
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-16
 HashCode:1996181658
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-17
 HashCode:1996181658
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-18
 HashCode:1996181658
The constructor is called
The constructor is called
Thread Name:From User ThreadFactory's localHost-Worker-19
 HashCode:1996181658
Thread Name:From User ThreadFactory's localHost-Worker-20
 HashCode:1996181658
The constructor is called
The constructor is called
The constructor is called

Process finished with exit code 0

标签: javamultithreading

解决方案


The second line is not equivalent to first, it is a Runnable that constructs an instance of MyRunnableThread but does not call its run() unless you add ".run()". Replace with:

thread.start();
thread = factory.newThread(() -> new MyRunnableThread().run());// SECOND WAY

The first constructs MyRunnableThread and lets the thread call MyRunnableThread.run(), in the second the thread runs the lambda which constructs MyRunnableThread and the MyRunnableThread.run() call only gets run if you add the ".run()" part


推荐阅读