Sleeping room

I have a problem with Java. I would like to write a program in which there is a Main class that has ArrayList Threads of some class (Task class) that just writes the letter and number. The Main object simply wakes up one stream from the ArrayList and allows it to do something while the same object (Main) sleeps in another.

It works fine: 0A, 0B, 0C, 1B, 1C, 1A, 2B, 2A, 2C, 3B, 3C, 3A, 4B, 4C, 4A, 5B, 5A, 5C,

but only if I Comment: e.printStackTrace () e is an exception then I get a lot of java.lang.IllegalMonitorStateException in java.lang.Object.notify (native method) on Main.run (Main.java:22)

Therefore, the notification does not work correctly, how should I wake him correctly, please tell me, show, correct. You are welcome,

import java.util.ArrayList;

import java.util.ArrayList;

public class Main extends Thread {
ArrayList<Thread> threads;

public Main() {
    super();
    threads = new ArrayList<Thread>();
}

public void run() {
    for (int i = 0; i < 3; i++) {
        threads.add(new Thread(new Task(i + 65)));
    }
    long cT = System.currentTimeMillis();
    for (int i = 0; i < threads.size(); i++) {
        threads.get(i).start();
    }
    while (System.currentTimeMillis() - cT < 10000) {
        for (int i = 0; i < threads.size(); i++) {
            try {
                threads.get(i).notify();
                // HOW TO WAKE THREAD FROM threads ArrayList
                Thread.sleep(1000);
                // how to put to bed the same thread ?
                threads.get(i).wait();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}

public static void main(String[] args) {
     new Main().start();
    //new Thread(new Task(65)).start();

}

}

N

public class Task implements Runnable {
int nr;
char character;

public Task(int literaASCII) {
    this.nr = 0;
    character = (char) (literaASCII);
}

@Override
public void run() {
    while (true) {
        try {
            System.out.print(nr + "" + character + ", ");
            nr++;
            int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)
            Thread.sleep(r);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}



public static void main(String[] args) {
    // TODO Auto-generated method stub

}
}
+3
4

sleep wait . sleep .

wait : wait , ( , ) , notify , , wait notify .

- , wait notify , , , (), , object.wait() object.notify() synchronized(object){ ... }. object.wait() synchronized -block, IllegalMonitorStateException.

for (int i = 0; i < threads.size(); i++) {
  threads.get(i).start();
} 

, , .

, , wait . :

public class Main extends Thread {
  //...

  public void run(){
    //Initialize all threads with common monitor object
    Object monitor = new Object();
    for (int i = 0; i < 3; i++) {
      threads.add(new Thread(new Task(i + 65, monitor)));
    }
    long cT = System.currentTimeMillis();
    for (int i = 0; i < threads.size(); i++) {
      //All threads will start, and immediately pause on monitor.wait()
      threads.get(i).start();
    }
    synchronized(monitor){
      while (System.currentTimeMillis() - cT < 10000) {
        //All threads are currently waiting, so we need to wake one random
        //thread up by calling notify on monitor. Other thread will not run yet,
        //because this thread still holds the monitor.
        monitor.notify();

        //Make this thread wait, which will temporarily release the monitor
        //and let the notified thread run.
        monitor.wait();
      }
    }
  }
}

//...

public class Task implements Runnable{
  int nr;
  char character;
  Object monitor;

  public Task(int literaASCII, Object monitor) {
    this.nr = 0;
    this.monitor = monitor;
    character = (char) (literaASCII);
  }

  @Override
  public void run() {
    synchronized(monitor){
      while (true) {
        //Pause this thread and let some other random thread
        //do the work. When other thread finishes and calls notify()
        //this thread will continue (if this thread is picked).
        monitor.wait();

        try {
          System.out.print(nr + "" + character + ", ");
          nr++;
          int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)

          Thread.sleep(r);
        } catch (Exception e) {
          e.printStackTrace();
        }

        //This thread has finished work for now. 
        //Let one other random thread know.
        monitor.notify();

        //Other thread will not be able to do work until this thread 
        //releases the monitor by calling monitor.wait() or 
        //completely exists the synchronized(monitor){ ... } block.
      }
    }
  }
}

, , , .

, notifyAll() notify(), notify(). notify() , "" , wait .

+11

wait() , ( , ):

, .

import java.util.ArrayList;

public class Main extends Thread {
    ArrayList<Thread> threads;

    public Main() {
        super();
        threads = new ArrayList<Thread>();

        for (int i = 0; i < 3; i++) {
            threads.add(new Thread(new Task(i + 65)));
        }

        for (int i = 0; i < threads.size(); i++) {
            threads.get(i).start();
        }

    }

    public void run() {
        long cT = System.currentTimeMillis();
        while (System.currentTimeMillis() - cT < 10000) {
            for (int i = 0; i < threads.size(); i++) {
                try {
                    synchronized (threads.get(i)) {
                        threads.get(i).notify();
                        // HOW TO WAKE THREAD FROM threads ArrayList
                        Thread.sleep(1000);
                        // how to put to bed the same thread ?
                        threads.get(i).wait();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

    }

    public static void main(String[] args) {
        new Main().start();
        // new Thread(new Task(65)).start();

    }

}

class Task implements Runnable {
    int nr;
    char character;

    public Task(int literaASCII) {
        this.nr = 0;
        character = (char) (literaASCII);
    }

    public void run() {
        while (true) {
            try {
                System.out.print(nr + "" + character + ", ");
                nr++;
                int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)
                Thread.sleep(r);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

}
+2

, ():

synchronized(threads.get(i)) {
    // how to put to bed the same thread ?
    threads.get(i).wait();
}
+1

, :

0A, 0B, 0C, 0D, 0E, 1A, 1B, 1C, 1D, 1E, 2A, 2B, 2C, 2D, 2E, stop 10 11 12 13 14 15

, sth, 0A, 1A (A 3000 ), 3 .. A, B, C, D, E, A, A, A, A, B, B, B....

But also I just can’t kill these threads, the cycle never ends, I would like to kill it until Main dies.

Thank you for all your comments.

import java.util.ArrayList;

public class Main extends Thread {
ArrayList<Thread> threads;

public Main() {
    super();
    threads = new ArrayList<Thread>();
}

 public void run(){

Object monitor = new Object();
for (int i = 0; i <= 5; i++) {
  threads.add(new Thread(new Task(i + 65, monitor)));
}
long cT = System.currentTimeMillis();
for (int i = 0; i < threads.size(); i++) {
  threads.get(i).start();
}
synchronized(monitor){
  while (System.currentTimeMillis() - cT < 10000) {
      try{

    monitor.notify();
    Thread.sleep(50);


    monitor.wait();}catch(Exception e){e.printStackTrace();}
  }

for(int i = 0; i < threads.size(); i++){
    System.out.println("I suspend "+threads.get(i).getId());
    threads.get(i).stop();
}


}
 }


 public static void main(String[] args) {
     new Main().start();
    //new Thread(new Task(65)).start();

}

}

N

public class Task implements Runnable {
int nr;
char character;
Object monitor;

public Task(int literaASCII, Object monitor) {
    this.nr = 0;
    this.monitor = monitor;
    character = (char) (literaASCII);
}

@Override
public void run() {
    synchronized (monitor) {
        while (true) {

            try {
                monitor.wait();

                System.out.print(nr + "" + character + ", ");
                nr++;
                int r = (int) ((Math.random() * 500) + 500); // <500ms,1000ms)

                Thread.sleep(r);
            } catch (Exception e) {
                e.printStackTrace();
            }

            monitor.notify();

        }
    }
}

}

0
source

All Articles