Having Thread reference as Class Level Property?
I have a situation where I need to call a method1() in class B from A. When method1() is calle开发者_JAVA百科d it creates a new Thread say(MyThread) and starts it immediately. In my case I am calling method1() from two different places in the application. I dont want to create a new instance of this thread every time. Inside method1() i tried checking if myThread.isAlive() before creating a new Instance of MyThread. But I get a compilation error MyThread needs to be initialized to call MyThread.isAlive(). So if put in a method property of type Thread ie.,
method() { Thread myThread; if(myThread.isAlive()) { return}; ..... }
Is it a good idea to declare a class level property in classB for Mythread and intialize it to null. Then inside method1() check the status of the thread if not running create a new one?
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();
}
You can do better by using an Executor, specifically a fixed thread pool. Create your thread pool in B's constructor and keep a private final reference to it. Then submit the Runnables in method1(), don't start a new thread.
This approach has several benefits: the Executor correctly handles thread lifecycle issues for you, you can change the threading model to say increase threads very easily, and there aren't any race conditions (in the thread initialization code - thanks commenters for pointing this out). There can be race conditions inside the Runnable that you're using.
Edited to add an example:
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;
}
This code will cause a NullPointerException
(NPE) to be thrown when you first call method1, because it'll attempt to invoke isAlive()
on null
. You need if(myThread != null && myThread.isAlive())
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();
}
}
精彩评论