我有一种情况需要从A调用B类中的method1()。当调用method1()时,它会创建一个新的Thread(MyThread)并立即启动它。在我的情况下,我从应用程序中的两个不同位置调用method1()。我不想每次都创建这个线程的新实例。在method1()里面,我尝试在创建一个新的MyThread实例之前检查myThread.isAlive()。但我得到一个编译错误MyThread需要初始化以调用MyThread.isAlive()。因此,如果放入Thread类型的方法属性,即
()的方法 { 线程myThread; 如果(myThread.isAlive()) {return}; ..... }
在MythB中为classB声明一个类级别属性并将其初始化为null是一个好主意。然后在method1()内部检查线程的状态,如果没有运行则创建一个新的?
class B()
{
Thread myThread = null;
public static B getInstance()
{
return B singleton object;
}
public void method1()
{
if(myThread.isAlive())
return;
myThread = new Thread(new Runnable(){
public void run(){
do some stuff.....
}).start();
}
==================
class A()
{
B.getInstance().method1();
}
==================
class someOtherClass()
{
B.getInstance().method1();
}
答案 0 :(得分:0)
当您第一次调用 method1 时,此代码将导致NullPointerException
(NPE)被抛出,因为它将尝试在isAlive()
上调用null
。您需要if(myThread != null && myThread.isAlive())
答案 1 :(得分:0)
使用Executor,特别是fixed thread pool,您可以做得更好。在B的构造函数中创建线程池并保留对它的私有最终引用。然后在method1()中提交Runnables,不要启动新线程。
这种方法有几个好处:Executor为您正确处理线程生命周期问题,您可以更改线程模型,以便非常轻松地增加线程,并且没有任何竞争条件(在线程初始化代码中 - 感谢评论者指出这一点)。您正在使用的Runnable中可能存在竞争条件。
编辑添加示例:
class B()
{
private final Executor threadPool = Executors.newFixedThreadPool(1);
private boolean taskSubmmitted = false;
public static B getInstance()
{
return B singleton object;
}
public synchronized void method1()
{
if(taskSubmitted)
return;
myRunnable = new Runnable(){
public void run(){
do some stuff.....
}};
threadPool.submit(myRunnable);
taskSubmitted = true;
}
答案 2 :(得分:0)
class B()
{
// class level variable works fine.... I dont see a problem
private Thread myThread = null;
public static B getInstance()
{
return B singleton object;
}
public void method1()
{
if(myThread != null && myThread.isAlive())
return;
myThread = new Thread(new Runnable(){
public void run(){
do some stuff.....
}).start();
}
}