Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Threading, suspending multiple other threads while one is running

I am trying to understand concurrency for part of an assignment I'm doing. I think I've got the basics done, but I'm getting stuck in the nuances of my usecase.

I apologize in advance if I haven't mastered the art of the question yet.

Basic idea:

I have a class, of which a few objects are instantiated as representations of parts of a houses and their only main function is to operate(). The catch is that when "Bell" operates, I want the others to wait(). My while statement is based on a bell toggle (boolean). If it is on - wait(), if not, carry on. It seems when running this program, I'm starving the other threaded objects for the sake "Bell".

Any thoughts on where I've gone wrong?

import java.util.ArrayList;

class Test extends Thread { 
  static int number = 0;
  private static final int TIMES = 30; 
  private static boolean bellstatus = false;
  private String name;
  private int val; 
 
   Test(String y,int x) { 
    number = number +1;
     val = x;
    name = new String(y);
  } 
  public void run() { // overrides default run() 
   
    for (int i=val; i>0; i--){ 
      System.out.println(name+" run() : " + i);
      operate();
    }
  }
  
  public synchronized void operate(){
   System.out.println(name+ " operating");
  
   while(bellstatus){
     try{
     System.out.println("Bell is ringing");
     wait();}catch(InterruptedException e){}
   }
   
   if(name.equals("Bell")){
     try{
     System.out.println("Bell working");
     bellstatus = true;
     Thread.sleep(500);
     Thread.yield();}catch(InterruptedException e){}
     bellstatus = false;
     notifyAll();
     System.err.println("Bell is done");
 }
   
   if(name.equals("Door")){
     try{
     System.out.println("Door working");
     Thread.sleep(500);}catch(InterruptedException e){}
   }
   if(name.equals("Window")){
     try{
     System.out.println("Window working");
     Thread.sleep(500);}catch(InterruptedException e){}
  }
  }     
  

  
  
public static void main(String arg[]) { 
   ArrayList<Test> example = new ArrayList();
    Test a = new Test("Bell",20);
    Test b = new Test("Door",20);
    Test c = new Test("Window",20);// create thread 
    
    example.add(a);
    example.add(b);
    example.add(c);
    
    System.out.println("Number of objects: "+a.number);
    for(int i = 0;i<example.size();i++)
      example.get(i).start();
    
    
                             // start thread run 
    
}
}
like image 701
HasanAlvi Avatar asked May 01 '26 00:05

HasanAlvi


2 Answers

Use just one thread and a queue of runnables. An executor with just one thread will queue your tasks until the one running is done https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executor.html

like image 200
eduyayo Avatar answered May 02 '26 14:05

eduyayo


Please don't use Raw Types (you could use the diamond operator <>). Then, if I understand your question, one possible solution is to use a ReentrantLock like,

static class Test extends Thread {
    static int number = 0;

    private static Lock lock = new ReentrantLock();
    private String name;
    private int val;

    Test(String y, int x) {
        number = number + 1;
        val = x;
        name = new String(y);
    }

    public void run() {
        for (int i = val; i > 0; i--) {
            System.out.println(name + " run() : " + i);
            operate();
        }
    }

    public synchronized void operate() {
        System.out.printf("%s operating%n", name);
        lock.lock();
        try {
            System.out.printf("%s working%n", name);
            Thread.sleep(500);
            System.out.printf("%s done%n", name);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public static void main(String arg[]) {
    List<Test> example = new ArrayList<>();
    Test a = new Test("Bell", 20);
    Test b = new Test("Door", 20);
    Test c = new Test("Window", 20);// create thread

    example.add(a);
    example.add(b);
    example.add(c);

    System.out.println("Number of objects: " + a.number);
    for (int i = 0; i < example.size(); i++) {
        example.get(i).start();
    }
    // start thread run
}
like image 34
Elliott Frisch Avatar answered May 02 '26 13:05

Elliott Frisch