Just started practicing multithreading. I came up with my own task:

It is a cup, completely filled with water. Every 3 seconds they drink 10% of the liquid. And every 6 seconds, pour 10% of the liquid. Draw it programmatically and calculate after how many seconds the cup will be empty.

I first implemented it in two cycles, but I realized that this is not what I need. As I understand it, there must be two streams living independently of each other. I have never done this and I did not succeed. I ask for help

Everything works fine at first, but as soon as the flow of drink empties the cup, the plus stream helps it to fill.

 public class Main { static int cap = 100; static int time = 0; static Thread plus; public static void main(String[] args) throws InterruptedException { Thread drink = new Thread(new Runnable(){ @Override public void run() { while (cap > 0) { try { Thread.sleep(3000); } catch (InterruptedException e) {} cap -= 10; System.out.println(cap); time += 3; } Thread.currentThread().interrupt(); plus.interrupt(); System.out.println(time); } }); plus = new Thread(new Runnable(){ @Override public void run() { while (cap > 0) { try { Thread.sleep(6000); } catch (InterruptedException e) {} cap += 10; System.out.println(cap); time += 6; } Thread.currentThread().stop(); } }); drink.start(); plus.start(); } } 
  • You also have an error in calculating the remaining capacity of the cup, and time, too. Try blocking the cup update section in both threads through lock(Object); - ArchDemon
  • Thread.currentThread (). stop() ; - deprecated !!! Never use this method! It leads to unpredictable consequences. - Oleksiy Morenets
  • You call interrupt() , but nowhere check the interrupt state of the thread. - Oleksiy Morenets
  • @ArchDemon, what is the calculation error? Regarding synchronization - I agree. But you can do with a couple of methods: synchronized void add() , synchronized void drink() - Oleksiy Morenets
  • Let's say it took 6 seconds. The first thread will make time += 3 + 3 , the second thread will make time += 6 . Total it turns out that 12 seconds have passed, which contradicts the initial conditions. The second assumption: let's say from a full mug drank and then poured. We consider 100 - 100 * 0.1 = 90, 90 + 90 * 0.1 = 99. You also get 100. - ArchDemon

1 answer 1

 public class Main { static int cap = 100; static int time = 0; static Thread plus; public static void main(String[] args) { Thread drink = new Thread(new Runnable() { @Override public void run() { drink(); } }); plus = new Thread(new Runnable() { @Override public void run() { add(); } }); drink.start(); plus.start(); } private synchronized static void add() { while (!Thread.interrupted() && cap > 0) { try { Thread.sleep(400); } catch (InterruptedException e) { break; } cap += 10; System.out.println("+ (" + cap + ")"); time += 6; } } private synchronized static void drink() { while (cap > 0) { try { Thread.sleep(200); } catch (InterruptedException ignored) { } cap -= 10; System.out.println("- (" + cap + ")"); time += 3; } plus.interrupt(); System.out.println(time); } } 
  • Wow. Honestly, I didn't know anything at all about the interrupt ... Okay, I will go read about the streams - Flippy
  • one
    Yes, this is a tricky thing. It does not interrupt the flow, but only sets the interrupt flag. And how to check it is a matter of the developer. - Olexiy Morenets
  • one
    Until I added break to catch nothing worked. That is ... interrupted is just some kind of indirect state that can be set to a thread and when Thread.sleep is thrown - Flippy
  • Is there an explanation about the removal of synchronized methods? - Flippy
  • one
    I changed a bit the code in the answer, because Indeed, a bit of "non-synchronized")). If you do not synchronize, it may happen that at the last step one thread enters the drink() method, reduces the cup variable to 0, reaches the interrupt() and the system switches threads. Accordingly, the second thread will not be able to interrupted and will perform the addition of water again. And we need it? - Oleksiy Morenets