One thread increases an integer named "counter" , and another decreases the same integer.
Using synchronized statement on LockObject to control access to counter.
If i understand correctly i have to use an Object reference.
Can i use synchronized statement on counter somehow?

public class Synchronized_Block_Demo {

        public static int counter=1;
        public static Object LockObject = new Object();

        public static void Show_LockObject(){
            System.out.println("LockObject = " + counter);
        }

           public static void main(String[] args) throws InterruptedException {
                Runnable r0=null,r1=null;
                Thread a,b;
                r0=new Thread_increases_LockObject(); 
                r1=new Thread_decreases_LockObject();
                a=new Thread(r0);
                b=new Thread(r1);
                a.start();
                b.start();
                a.join();
                b.join();
                System.out.print("Threads finished!");
          }

    }

    class Thread_increases_LockObject implements Runnable{
        public void run(){

             try {

                 for(int i=0;i<10;i++){
            Synchronized_Block_Demo.counter += 2;
            Synchronized_Block_Demo.Show_LockObject();
            synchronized (Synchronized_Block_Demo.LockObject) {
                    Synchronized_Block_Demo.LockObject.notify();
                    Synchronized_Block_Demo.LockObject.wait();

        }   
        }
             }
           catch(InterruptedException e){}
    }
    }


    class Thread_decreases_LockObject implements Runnable{
        public void run(){

            try {

                for(int i=0;i<10;i++){
             synchronized(Synchronized_Block_Demo.LockObject){
                    Synchronized_Block_Demo.LockObject.wait();
            }

            Synchronized_Block_Demo.counter -= 1;
            Synchronized_Block_Demo.Show_LockObject();
            synchronized (Synchronized_Block_Demo.LockObject) {
         Synchronized_Block_Demo.LockObject.notify();
        }  
            }

        } catch(InterruptedException e){}

    }
    }

I believe the lock item has to be an object as well so if you wanted to put a lock on the counter you would have to use the Integer type instead of the primitive "int".

I tried it , did not work because Thread_increases_LockObject runs , increases counter (Integer type) to 3 , and then both threads stop. I caused a deadlock but why?

I'm trying to make it work but I don't think that a lockobject can modify itself. But ofcource the Integer type can be used in a synchronized statement.

After wait() cannot modify itself , so no way to solve this. I'm sorry for this post.

Lines 52-54 you have a synch block in which you wait on the lock object. But no other thread can get the lock to execute their notify, so the app hangs.

Just synching on the same lock object will prevent simultaneous access from different threads. YOu only need to get into wait/notify if you want to force some kind of management of which thread runs when, eg to make them alternate strictly.

Don't use a "sync" AT ALL. See the API docs for AtomicInteger.

And about using Integer for counter? No way. Each "increment" will create a NEW Integer, thereby changing the object on which to look.

Thank you all for your answers.
The following works fine. AtomicInteger is an acceptable argument for synchronized statement. masijade was right about Integer type. I used sync though because i wanted the correct output messages.

import java.util.concurrent.atomic.AtomicInteger;
public class Atomic_Integer_Demo {    

   public static AtomicInteger counter = new AtomicInteger(1);

    public static void Show_AtomicInteger(){
        System.out.println("AtomicInteger = " + counter);
    }

       public static void main(String[] args) throws InterruptedException {
            Runnable r0=null,r1=null;
            Thread a,b;
            r0=new Thread_increases_AtomicInteger(); 
            r1=new Thread_decreases_AtomicInteger();
            a=new Thread(r0);
            b=new Thread(r1);
            a.start();
            b.start();
            a.join();
            b.join();
            System.out.print("Threads finished!");
      }    
}

class Thread_increases_AtomicInteger implements Runnable{
    public void run(){
     try {
        for(int i=0;i<10;i++){
           Atomic_Integer_Demo.counter.addAndGet(2);
           Atomic_Integer_Demo.Show_AtomicInteger(); 
           synchronized (Atomic_Integer_Demo.counter) {
             Atomic_Integer_Demo.counter.notify();
             Atomic_Integer_Demo.counter.wait();
           } 
         }
      }
       catch(InterruptedException e){}
     }    
    }

class Thread_decreases_AtomicInteger implements Runnable{
    public void run(){
       try{
         for(int i=0;i<10;i++){
           synchronized (Atomic_Integer_Demo.counter) {
             Atomic_Integer_Demo.counter.wait();
           }     
           Atomic_Integer_Demo.counter.addAndGet(-1);
           Atomic_Integer_Demo.Show_AtomicInteger();    
           synchronized (Atomic_Integer_Demo.counter) {
             Atomic_Integer_Demo.counter.notify();
           }     
        }
       } catch(InterruptedException e){}
     }    
    }
This question has already been answered. Start a new discussion instead.