Java - остановить поток с общим объектом

1

Я хочу использовать общий объект для остановки потоков. Поэтому код, который я написал, прост.

Основной метод создает и запускает потоки, после чего он ждет 800 мс, после чего устанавливает атрибут общего объекта на "false".

Потоки находятся в busywait, если атрибут общего объекта "true".

Код не работает (возникает бесконечный цикл), кажется, что существует проблема взаимного исключения, которую я не могу объяснить, потоки ТОЛЬКО читают этот атрибут.

Может ли кто-нибудь объяснить мне это, пожалуйста? :)

Главный

public class SharedResThreadExt {
public static void main(String args[]) {
    BodyThread[] my_threads = new BodyThread[5];               

    SharedRsrc sh_resource = new SharedRsrc(true);   // shared object dec and alloc

    for (int i = 0; i < my_threads.length; i++) {    // creation and start threads
        my_threads[i] = new BodyThread(sh_resource);         
        my_threads[i].start();
    }

    try{
        Thread.sleep(800);          // wait 800 millisec 
        sh_resource.setFlag(false);  //sets shared object attribute to false
    }
    catch(InterruptedException e){}
}
}

Корпус нитей

class BodyThread extends Thread {                    
private SharedRsrc sr;        

public BodyThread(SharedRsrc sr){
    this.sr = sr;
}

@Override
public void run() {
    System.out.println("Thread: " + getId() + " starts exec.");
    while(sr.getFlag()){}              // busywait if shared object attributeis true  
    System.out.println("Thread: " + getId() + " stopped exec.");
}
}

Общий объект

class SharedRsrc{
private boolean flag;

public SharedRsrc(boolean flag){
    this.flag = flag;
}
public boolean getFlag(){
    return this.flag;
}
public void setFlag(boolean flag){
    this.flag = flag;
} 
}
  • 0
    volatile flag
  • 0
    Чтобы уточнить, значение flag читается один раз и кэшируется потоками; вам нужно убедиться, что он либо volatile либо сделать метод synchronized чтобы вызвать «сброс» или «перезагрузку».
Показать ещё 1 комментарий
Теги:
multithreading

1 ответ

1
Лучший ответ

изменить общий объект

Из:

class SharedRsrc{
private boolean flag;

public SharedRsrc(boolean flag){
    this.flag = flag;
}
public boolean getFlag(){
    return this.flag;
}
public void setFlag(boolean flag){
    this.flag = flag;
} 
}

Для того, чтобы:

   class SharedRsrc{
   private volatile boolean flag;

    public SharedRsrc(boolean flag){
        this.flag = flag;
    }
    public boolean getFlag(){
        return this.flag;
    }
    public void setFlag(boolean flag){
        this.flag = flag;
    } 
    }

Или вы можете объявить переменную непосредственно в SharedResThreadExt как SharedResThreadExt ниже.

private static volatile boolean flag= false;

Если вы не хотите использовать volatile тогда второй вариант - использовать synchronized

  • 0
    Зачем менять его на static ?
  • 0
    у вас тоже нет :) я поставил его в качестве примера и обновлю сейчас, чтобы соответствовать :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню