[英]Understanding Threads implementing Runnable in java
我试图了解Java中的线程。 我创建了一个实现Runnable
接口的线程,该接口执行某个类的某个功能。 以下是Java类:
MyThread Class
public class MyThread implements Runnable {
private DataContainer dataContainer;
private Thread thread;
public MyThread(DataContainer dataContainer) {
this.dataContainer = dataContainer;
thread = new Thread(this);
thread.start();
thread.setName("Thread 2");
}
@Override
public void run() {
System.out.println("MyThread : "+dataContainer.toString());
}
public void runThread() {
thread.run();
}
}
DataContainer Class
。 我在线程中执行的功能
public class DataContainer {
private static DataContainer instance = null;
private DataContainer() {}
public static DataContainer getInstance() {
if(null == instance)
instance = new DataContainer();
return instance;
}
@Override
public String toString() {
return Thread.currentThread().getName()+" : __Data__";
}
}
main class
public class Launcher {
public static void main(String[] args) {
DataContainer dataContainer = DataContainer.getInstance();
MyThread myThread = new MyThread(dataContainer);
int i =0;
while(i++<10) {
System.out.println("Launcher : "+ dataContainer.toString());
myThread.runThread();
}
}
}
问题是,在while
循环中,从主类和myThread实例执行dataContainer.toString()时,我得到了输出,因为它们都在一个线程中运行: main thread
。 循环中的所有执行都不是从Thread 2
执行的。
我的目标是, in the while loop, I want myThread.runThread()
在线程Thread 2
下执行。
编辑:
添加了thread.start()
。 但是,现在只执行一次? 我每次想执行myThread.runThread()时都无法创建新线程。 通过在循环中创建一个新线程,我最终将创建一堆线程。 这是明智的吗? 我希望某个线程(例如X)执行某段代码(例如Y)。 每次必须执行Y时,都应该通过线程X完成。
解
这可能是一种解决方案:
public class MyThread implements Runnable {
private DataContainer dataContainer;
private Thread thread = null;
public MyThread(DataContainer dataContainer) {
this.dataContainer = dataContainer;
}
@Override
public void run() {
System.out.println("MyThread : "+dataContainer.toString());
}
public void runThread() {
boolean threadIsAlive = (null!=thread && Thread.getAllStackTraces().keySet().contains(thread));
if(null == thread || !threadIsAlive) {
thread = new Thread(this);
thread.start();
} else {
thread.run();
}
}
}
thread.run();
只是在当前线程的上下文中直接调用您的Runnable
的run
方法。 如果在runThread
方法中简单地调用run()
, runThread
获得相同的结果。
您需要调用thread.start()
,这将创建一个新的进程线程,并最终调用您的Runnable
的run
方法
而不是包装一个Thread
,而不是一个Runnable
,这是违反直觉的,一般不好的设计,您应该创建Thread
和设定Runnable
到它时,你需要,例如...
public class MyThread implements Runnable {
private DataContainer dataContainer;
public MyThread(DataContainer dataContainer) {
this.dataContainer = dataContainer;
}
@Override
public void run() {
System.out.println("MyThread : "+dataContainer.toString());
}
}
然后您可以做类似...
DataContainer dataContainer = DataContainer.getInstance();
MyThread myThread = new MyThread(dataContainer);
Thread thread = new Thread(myThread );
thread.setName("Thread 2");
thread.start();
System.out.println("Launcher : " + dataContainer.toString());
myThread.runThread()
只会在当前线程中调用该方法。 如果希望在新线程中执行该调用,请将该调用放入run
方法,然后调用myThread.start()
。 这将启动另一个线程并调用可运行对象的run方法。
在定义实现Runnable的类时,不需要在其中具有Thread对象。
简单地
class myThread implements Runnable {
@Override
public void run() {
// do something
}
}
new Thread (new myThread ()).start ();
我没有试图理解您的示例(太费解了),但这是一个坏主意:
public class Foobar implements Runnable {
private XType x;
private YType y;
private Thread thread;
public Foobar() {
x = new XType();
thread = new Thread(this); //Not in a constructor!!!
thread.start();
y = new YType();
}
@Override
public void run() {
doSomethingWith(y); // y can be uninitialized at this point.
doSomethingElseWith(x); // x can be uninitialized too!!!
}
}
这种反模式都有一个名字,这就是所谓的“跑冒滴漏this
从一个构造函数。” Foobar构造函数启动新线程,并在完全初始化新对象之前为其提供对新Foobar实例(即this
)的引用。 Java语言规范不保证当以这种方式发布对象时,该对象在新线程中的外观如何。 (Google用于“安全发布”)
特别是,当首次输入run()方法时,从新线程的角度看,该对象的任何成员变量(包括x !!)似乎都未初始化。
最佳实践:永远不要在构造函数中或构造函数调用的任何辅助方法中使用this
方法,也不要将辅助函数声明为final
以便子类无法覆盖一个子类并查看未初始化的对象那样。
class Foobar {
Foobar(...) {
...don't use "this" here...
fooHelper(...);
}
private final void fooHelper(...) {
...don't use "this" here either...
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.