Search code examples
javamultithreadingsynchronize

Waiting for only a Part of another Thread - Java


I have the following scenario ... there are 2 DJs who are trying to play music, but they can obviously play a CD only if the other DJ is not playing the same CD at that moment so i have those classes and im trying to use synchronize to lock a CD for the other Thread

public class cd {
    private boolean played = false;    
    public void play() {
        this.played = true;
        Thread.sleep(2000);       
    }

    //other methods, e.g. skip a song or put the CD back in the collection

    public boolean isAvailable() {
        return !(this.played);
    }
}

public class turntable {
    private boolean used = false;   

    public void use() {
        this.played = true;
        Thread.sleep(2000);       
    }

    public boolean isFree() {
        return !(this.used);
    }

    ...

}

DJ class:

public class DJ implements Runnable {
    CD disk;
    Turntable tt;

    //constructor

    public void run() {

        //do something else, e.g. go to the bar

        tt.use();    
        disk.play();
        disk.skipSong();
        disk.putBack();
        tt.leave();

        //do something else, e.g. smoke a cigarette
    }
}

And now I'm trying to block the current CD for the DJ_2 while DJ_1 is in this part:

Part that should block the CD:

tt.use();    
disk.play();
disk.skipSong();
disk.putBack();
tt.leave();

But the CD should be obviously available, if DJ_1 put it back but is smoking a cigarette now.

So my question is ... how can i block only a part of the run method of a thread and set it in relation to the same part of a different Thread (keep in mind im trying to solve the problem with synchronized)


Solution

  • For the play method in CD class

    public synchronized void play() {
        while(this.played) {
            try {
                wait();
            } catch (InterruptedException e) {}
        }
    
        this.played = true;
    
        // suppose each DJ can play the disk for 2 seconds and then has to yield the fun to others 
        Thread.sleep(2000);
        this.played = false;
        notifyAll();     
    }
    

    Then each thread should have the same CD instance

    public static void main(String){
        CD cd = new CD();
    
        DJ dj1 = new DJ();
        dj1.disk = cd;
        Thread threadDJ1 = new Thread(dj1);
    
        DJ dj2 = new DJ();
        dj2.disk = cd;
        Thread threadDJ2 = new Thread(dj2);
    
        threadDJ1.start();
        threadDJ2.start();
    }
    

    The Java documentation has good example on this kind of topic Guarded Blocks