简体   繁体   中英

Java - Stop thread with shared object

I want to use a shared object to stop threads. So the code I wrote is simple.

The main method creates and starts threads, then it waits for 800 ms, after that, sets attribute of shared object to "false".

The threads are in a busywait if attribute of shared object is "true".

The code doesn't work (an infinite loop occurs), it seems there is a mutual exclusion problem that I can't explain, threads ONLY read that attribute.

Can anyone explain to me this, please? :)

Main

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){}
}
}

Threads body

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.");
}
}

Shared Object

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

change Shared Object

From:

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

To:

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

Or you can declare variable directly in SharedResThreadExt as below.

private static volatile boolean flag= false;

If you dont want to use volatile then second option is to use synchronized

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM