问题
When I start new thread in traditional constructor, NetBeansIDE gives no warnings:
addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
(new SomeThread()).start();
}
});
But if I convert it to Lambda expression, I'm getting a warning "Starting new Thread in constructor":
addActionListener((ActionEvent e) -> {
(new SomeThread()).start();
});
What is the problem here? What is the correct solution?
EDIT 1:
The same problem on NetBeans IDE 8.0.2:
The code:
import java.awt.event.ActionEvent;
import javax.swing.Timer;
public class TimerClass extends Timer {
public TimerClass() {
super(1000, null);//Loop 1 sec
addActionListener((ActionEvent e) -> {
(new SomeClass()).start();
});
}
private class SomeClass extends Thread {
@Override
public void run() {
}
}
}
回答1:
The problem here is that it's considered dangerous to start a thread or even register a listener in a constructor.
Explanation:
An inner class contains a reference to its enclosing class meaning that the thread that you started in your constructor has a reference to the TimerClass
object's state before the constructor returned. So the new thread might see a partially constructed object with stale values (values that are current in one thread but not for others).
A simple fix:
Make the constructor private and then make a public and static factory method that creates the object and starts the thread.
import java.awt.event.ActionEvent;
import javax.swing.Timer;
public class TimerClass extends Timer {
// notice that the constructor is now private.
private TimerClass() {
super(1000, null); //Loop 1 sec
}
// This will create the instance and then register the listener and start the thread
public static TimerClass createInstance() {
TimerClass instance = new TimerClass();
instance.addActionListener((ActionEvent e) -> {
(instance.new SomeClass()).start();
});
return instance;
}
private class SomeClass extends Thread {
@Override
public void run() {
}
}
}
With this, the thread will see a fully constructed object and thread safety will be restored (thus removing the warning).
来源:https://stackoverflow.com/questions/28924678/starting-new-thread-in-constructor-warning-in-lambda-expression-netbeans-ide