2010-11-11 2 views
0

У меня возникла ситуация, когда мне нужно вызвать метод1() в классе B из A. Когда вызывается метод1(), он создает новый Thread say (MyThread) и запускает его немедленно. В моем случае я вызываю метод1() из двух разных мест приложения. Я не хочу каждый раз создавать новый экземпляр этого потока. Внутри метода1() я попытался проверить, если myThread.isAlive() перед созданием нового экземпляра MyThread. Но я получаю ошибку компиляции. MyThread необходимо инициализировать, чтобы вызвать MyThread.isAlive(). Поэтому, если ввести свойство метода типа Thread ie.,Ссылка на тему как свойство уровня класса?

method() { { Thread myThread; if (myThread.isAlive()) {return}; .....

Это хорошая идея объявить свойство уровня класса в классеB для Mythread и инициализировать его до нуля. Затем внутри метода1() проверить статус потока, если он не запущен, создать новый?

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

Вы можете сделать лучше с помощью Executor, в частности fixed thread pool. Создайте пул потоков в конструкторе B и сохраните окончательную ссылку на него. Затем отправьте Runnables в метод1(), не запускайте новый поток.

Этот подход имеет несколько преимуществ: Исполнитель правильно справляется с проблемами жизненного цикла резьбы для вас, вы можете изменить модель потоковой передачи, чтобы сказать, что поток увеличивается очень легко, и нет никаких условий гонки (в коде инициализации потока - спасибо комментаторам для указания этого). В Runnable могут быть условия гонки, которые вы используете.

Edited добавить пример:

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; 
    } 
+0

Выглядит отлично! но не могли бы вы объяснить мне немного больше с измененными фрагментами кода моего кода? – AKh

+1

Вы можете узнать об этом самостоятельно, прочитав соответствующие учебные пособия по Java; например http://download.oracle.com/javase/tutorial/essential/concurrency/executors.html –

+1

В начале потока не может быть никаких условий гонки, но они все еще существуют при выполнении задач, если вы не используете один исполнитель потока. –

0

Этот код вызовет NullPointerException (NPE), который будет брошен, когда вы первый вызов method1, потому что он будет пытаться вызвать isAlive() на null. Вам необходимо if(myThread != null && myThread.isAlive())

+0

Да я забыл упомянуть, что в коде .. но я на самом деле есть на месте. – AKh

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(); 
    } 
}