1

I have some problem about the synchronization of two threads.

This is the main:

public class Main {
    public static void main(String[] args) throws InterruptedException {
        new Thread(new TaskA()).start();
        //Thread.currentThread().sleep(3000);
        new Thread(new TaskB()).start();
    }
}

and these are my two thread that increment/decrement a shared variable "count"

public class TaskA extends Manager implements Runnable {

    @Override
    public void run() {

        while(true){

        try {
            decrement();
            System.out.println("Thread A: " + getCount());
            Thread.sleep((long) Math.random()%4000);
        }catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
    }
}
public class TaskB extends Manager implements Runnable {
    @Override
    public void run() {
        while(true){
            try {
                increment();

                System.out.println("Thread B: " + getCount());
                Thread.sleep((long) Math.random()%4000);


            }catch(Exception e){
                System.out.println(e.getMessage());
            }
        }
    }
}

Operation are managed by this class:

public class Manager {

    private int count=0;

    public synchronized void increment() throws InterruptedException {
        if(count>=0){
            count++;
        }else {
            wait();
            notifyAll();
        }

    }
    public synchronized void decrement()throws InterruptedException {
        //wait();
        if(count <10){
            count--;
        }else {
            wait();
            notifyAll();
        }

    }
    public synchronized int getCount(){
        return count;

    }}

This is the output that I expect:

-ThreadA: 1 
-ThreadA: 2
-ThreadA: 3
    .
    .
-ThreadB: 10 
-ThreadB: 9
-ThreadB: 8
    .
    .
-ThreadA: 1 
-ThreadA: 2
-ThreadA: 3
    .
    .
Mureinik
  • 297,002
  • 52
  • 306
  • 350

1 Answers1

1

Your count is an instance variable, as is the synchronization mechanism. If you want to share them between different instances, they need to be static:

public class Manager {

    // Made static so that all managers share the same count
    private static int count = 0;

    public void increment() throws InterruptedException {
        // Synchronizing on a resource shared between all instances:
        synchronized (Manager.class) {
            if (count >= 0) {
                count++;
            } else {
                wait();
                notifyAll();
            }
        }
    }

    public void decrement() throws InterruptedException {
        // Synchronizing on a resource shared between all instances:
        synchronized (Manager.class) {
            //wait();
            if (count < 10) {
                count--;
            } else {
                wait();
                notifyAll();
            }
        }
    }

    public int getCount() {
        // Synchronizing on a resource shared between all instances:
        synchronized (Manager.class) {
            return count;
        }
    }}
Sambit
  • 7,625
  • 7
  • 34
  • 65
Mureinik
  • 297,002
  • 52
  • 306
  • 350
  • 1
    As Sambit pointed out in the question's comments, I'm surprised you don't use `java.util.concurrent.atomic.AtomicInteger`, a class purpose built for this exact type of situation. – Powerlord May 25 '19 at 07:34