Я хочу использовать общий объект для остановки потоков. Поэтому код, который я написал, прост.
Основной метод создает и запускает потоки, после чего он ждет 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;
}
}
изменить общий объект
Из:
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
static
?
volatile flag
flag
читается один раз и кэшируется потоками; вам нужно убедиться, что он либоvolatile
либо сделать методsynchronized
чтобы вызвать «сброс» или «перезагрузку».