I have a public class change which holds the private static int commonresource and the methods :
public synchronized void increment(int inc)
public synchronized void decrement(int inc)
to handle the variable commonresource

I have a main class which starts 2 new threads "nikos" , "fosses"
with a constructor that takes as an argument an instance of class change.
change ch = new change();
(new Thread(new nikos(ch))).start();
(new Thread(new fosses(ch))).start();

nikos increments in a 10-times loop variable commonresource by 5 by calling ch.increment(5)
fosses decrements in a 10-times loop variable commonresource by calling ch.decrement(1);

package Threads;
 public  class change{
      private static  boolean flag = false;
      private static  int commonresource=1;
     public synchronized void increment(int inc) {
        while (flag){
             try{
                 wait();
             } catch (InterruptedException e) {}
         }
         flag = true;
         {
     System.out.println("before increment :"+commonresource);
     commonresource   += inc;
     System.out.println(Thread.currentThread().getName()+" increment by "+inc);
     System.out.println("after increment :"+commonresource);}
          notify();
    }
    public synchronized void decrement(int inc) {
         while (!flag){
             try{
                 wait();
             } catch (InterruptedException e) {}
         }
         flag = false;
         {
    System.out.println("before decrement :"+commonresource);
     commonresource   -= inc;
     System.out.println(Thread.currentThread().getName()+" decrement by "+inc);
     System.out.println("after decrement :"+commonresource);}
      notify();
    }
    }
package Threads;
  public class fosses implements Runnable {
    private change ch;
    public fosses(change ch) {
        this.ch = ch;
    }
    @Override
    public void run() {
        for(int i =0; i<10;i++)
        ch.decrement(1);
       }
    }
package Threads;
  public class nikos implements Runnable {
    private change ch;

    public  nikos(change ch) {
        this.ch = ch;
    }

    @Override
    public void run() {
        for(int i =0; i<10;i++)
        ch.increment(5);

       }
    }
package Threads;
public class fossesrunnable {
  
   public static void main(String args[]) {
         change ch = new change();
          (new Thread(new nikos(ch))).start();
          (new Thread(new fosses(ch))).start();
}}

This code seems to work fine but my question is :
Is there any other way to synchronize these two threads than trying to avoid a deadlock in class change body?

Recommended Answers

All 4 Replies

You shouldn't need to be doing all of that at all. With the methods being synchronised, the synchronisation is taken place on the instance of change anyway, so only one thread will have access to the instance at one time already anyway.

And, since they both get the same instance of change, then that "commonresource" variable should be an instance variable and not a class variable (iow it should not be static).

Thanks for the reply. I have tried it but the output was a chaos.Probably cause of the println methods. There was no consistency at all.

Okay? And? Try adding a simple sleep for, say 20 milliseconds, after the println, and see how it looks then. When you use System.out you are, essentially, giving up the output to another thread to actually throw out to the screen (among other things) and that will make this seem chaotic. Add a sleep to give it a bit of time. Better, would be to define a List in that "change" class and, rather than printing the sctrings, simply adding the strings to the list, and printing the entire list at the end. As long as the "add" takes place in the synchorinzed methods you will see the "flow" statements in the proper order.

Even more elegant, would be to use a ConcurrentLinkedQueue and add the strings to that and start another thread that does nothing but read this queue and print the strings contained therein. That should, also, give you the output in the proper order.

What excatly do you want to achieve? It looks like you want the two threads to alternate (each method waits for the other method to execute exactly once before it runs, regardless of the threading) - in which case I don't think you'll get a much better solution than your synchronised methods and a boolean to control alternation. But m. is right - your variables should not be static.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.