9

in my application i am using a code that run a batch file, on executing it i am getting a exception i.e. current thread is not owner. Here i want to mention that my application is based on eclipse plugin development. Following is my code, please have a look and find out what is the problem to help me..

/*.......any code.........*/
try
{
    Runtime runtime = Runtime.getRuntime();
    String cmd = new String(C:\\abc.bat);
    process = runtime.exec("\"" + cmd + "\"");

    process.wait();

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

/***********any code**************/
Andrew Eisenberg
  • 28,387
  • 9
  • 92
  • 148
RTA
  • 1,251
  • 2
  • 14
  • 33
  • 3
    Note that `process.wait` *almost certainly* does **not** do what you want it to do. You probably want to call [`waitFor()`](http://docs.oracle.com/javase/7/docs/api/java/lang/Process.html#waitFor()), which will also solve your problem. – Joachim Sauer May 24 '13 at 08:01
  • 1
    You are going to need to be more specific. What are you trying to do? As @JoachimSauer mentions, `wait()` is almost certainly wrong. What are you trying to do. Note that I removed the eclipse-plugin tag since this question has nothing to do with plugins. If it does, you should edit the question so that the eclipse-plugin relevancy is explicit. – Andrew Eisenberg May 24 '13 at 17:00

4 Answers4

20

The wait is the method owned by Object, to use the method, you must get the lock of the object, change your code to,

try
{
    Runtime runtime = Runtime.getRuntime();
    String cmd = new String(C:\\abc.bat);
    process = runtime.exec("\"" + cmd + "\"");
    synchronized (process){
       try{
          process.wait();
       } catch (InterruptedException e) {
          e.printStackTrace();
       }
    }
}
catch (Exception e)
{
   e.printStackTrace();
}
Stony
  • 3,541
  • 3
  • 17
  • 23
  • 1
    Reasonable answer. Don't know why it was down-voted. Upvoting, even though it is probably not the correct answer. – Andrew Eisenberg May 24 '13 at 17:01
  • Likely, because that's not what author originally wanted to do. He didn't expect to use synchronization at all. – mmelnik Jul 16 '22 at 11:32
  • you may find this useful as well -> The difference between Synchronized blocks with wait/notify and without them (https://stackoverflow.com/a/7842289/5308115) – yashodha_h May 29 '23 at 09:39
1

Use BLocking Queues: Cleanest approach as well as advanced. Auto generate: start with 1 and keep adding to the other ques in the process.

public class MyClass {
    public static void main(String args[]) {
        MyClass clas = new MyClass();
        int max = 20;
        BlockingQueue<Integer> eq = new LinkedBlockingQueue();
        BlockingQueue<Integer> odd = new LinkedBlockingQueue();
        odd.add(1);
        clas.startB(max,clas,odd,eq);
    }
    public void startB(final int max, Object clas,BlockingQueue<Integer> oq,
            BlockingQueue<Integer> eq) {
        Runnable even = () -> {
            int num = 0;
            while(num < max) {
            try {
                num = eq.take();
                if( num%2==0) {
                    System.out.println(num);
                    oq.add(num+1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }}
        };
        Runnable odd = () -> {
            int num = 0;
            while(num < max) {
            try {
                if( (num = oq.take())%2==1) {
                    System.out.println(num);
                    eq.add(num+1);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }}
        };
        new Thread(even).start();
        new Thread(odd).start();
    }
keshav
  • 41
  • 3
0

I assume you were confused by the wait() method name, thinking it may allow you to wait until exec() is finished, but really it's not and has completely different purpose.

What I believe you wanted here is to call Process.waitFor() method:

try {
    Runtime runtime = Runtime.getRuntime();
    String cmd = new String(C:\\abc.bat);
    process = runtime.exec("\"" + cmd + "\"");
    process.waitFor();
} catch (Exception e) {
    e.printStackTrace();
}

which should do what you may originally expected — to wait until batch execution is finished.

On the other hand, wait() method in Java (which comes from Object.wait()) is related to multi-threading programming and to Java implementation of the monitor thread synchronization concept. Historically, it was put to the main Object.java class, so all classes inherit it and that's what confusion may come from.

In your example it's definitely not the right method to call. And the IllegalStateMonitor exception message you're getting:

current thread is not owner

tries to give you an implicit hint on threads synchronization issue. Though again, when you're not using multi-threading in your code it may confuse you a lot and doesn't provide any clue what could go wrong, as you not expecting it.

wait() method should only be called on the monitor objects, when you're writing code inside of synchronized blocks or methods, e.g.:

private final List<Task> tasks = new ArraList<>();

private synchronized void waitForTasks() throws InterruptedException {
    // because 'synchronized' word used on method,
    // here monitor is the whole class, i.e. 'this'
    if (tasks.isEmpty()) {
        wait(); // method is called on the class itself, as it's the monitor object
    }
    doTasks();
}

or:

private final List<Task> tasks = new ArraList<>();

private void waitForTasks() throws InterruptedException {
    synchronized (tasks) { // monitor object is set to 'tasks' object
        if (tasks.isEmpty()) {
            tasks.wait();  // method is called on the monitor
        }
        doTasks();
    }
}

If you would like to get more information on monitor concept in Java, you can this nice article on the topic.

mmelnik
  • 583
  • 5
  • 12
0

This will help, use the runnable to create 2 threads responsible for printing even and odd thread and provide the resource to it.

public class MyClass {
    volatile int counter = 1;
    public static void main(String args[]) {
        MyClass clas = new MyClass();
        int max = 20;
        clas.start(max,clas);
    }
    public void start(final int max, Object clas) {
        Runnable even = () -> {
            synchronized(this) {

                while(counter<= max){
                    if(counter % 2 ==0) {
                        System.out.println("even  "+counter);
                        counter++;
                        clas.notify(); 
//no ncecessory to use clas.notify, just notify() / wait() also works

                    }else{
                        try{
                            clas.wait();
                        }catch(Exception e) {System.out.println(e);}
                    }
                }
            }
        };

        Runnable odd = () -> {
            synchronized(this) {
                while(counter<= max){
                    if(counter % 2 ==1) {
                        System.out.println("odd "+ counter);
                        counter++;
                        clas.notify();

                    }else{
                        try{
                            clas.wait();}catch(Exception e) {System.out.println(e);}
                    }
                }
            }
        };
        new Thread(even).start();
        new Thread(odd).start();
    }
}
keshav
  • 41
  • 3
  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/32481555) – new Q Open Wid Aug 18 '22 at 16:59