Kevin Rave
Kevin Rave

Reputation: 14456

Method call from thread does not finish - How to end the thread - Workaround

I have a following code.

ReadWriteLock someLock = new ReentrantReadWriteLock();
Condition someCondition = someLock.writeLock().newCondition();

public someMethod() {
    // do some stuff
    someCondition.await(); //Lock here.
    System.out.prinltn("This never prints");
}

public doSomeStuff() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                someMethod();
                System.out.println("thread finished");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("thread is going to die");
        }
    }).start();
}

When the thread calls the method someMethod() it gets executed. But since there is an await() method on that function. It never ends / it does not print 'This never prints', unless its woken up by singnalAll(). But I want the thread to be finished once its executed.

I cannot refactor the whole thing. I just need a workaround to this problem. Its used in Swing application. So thread is important.

Upvotes: 2

Views: 276

Answers (3)

james007
james007

Reputation: 741

Two ways you can sort this out.

1) Design your task with Interruption Policy

Do a defensive coding. If your task is interrupted by any means, the program should know how to deal with that.

2) Add a POISON PILL as in this example, Once you

public someMethod() {
    while(condition predicate){
    someCondition.await(TIME_OUT); //Lock here.
}
//ADD Poison pill here
    System.out.prinltn("This never prints");
}    

As Per Java Concurrency in Practice

When using condition waits (Object.wait or Condition.await):

1)Always have a condition predicate some test of object state that must hold before proceeding;

2)Always test the condition predicate before calling wait, and again after returning from wait;

3)Always call wait in a loop;

4)Ensure that the state variables making up the condition predicate are guarded by the lock associated with the condition queue;

5) Hold the lock associated with the the condition queue when calling wait, notify, or notifyAll; and

6)Do not release the lock after checking the condition predicate but before acting on it.

Upvotes: 1

Nipun Gupta
Nipun Gupta

Reputation: 33

I am not sure if I understood your question correctly but I think you want to start the someMethod() function and then make the caller exit without waiting for someMethod() to finish. This means you are basically branching your execution flow into two, one where the someMethod() running waiting for its due awakening and the other where the caller just continues on(which it will need to do if you want it to finish) after calling someMethod(). To do this you will have to run someMethod() in a separate thread. Something like this.

public doSomeStuff() {
    new Thread(new Runnable() {
        @Override
        public void run() {
        try {
            new Thread(){
                public void run(){
                    someMethod();
                }
            }.start();
            System.out.println("thread finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread is going to die");
    }
  }).start();
}

Upvotes: 1

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45596

I think, this will do:

Thread thread =
  new Thread(new Runnable() {
    @Override
    public void run() {
        try {
          someMethod();
          System.out.println("thread finished");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread is going to die");
    }
  });

thread.start( );

final long reasonableTimeout = ...;

thread.join( reasonableTimeout );

// THIS WILL SHAKE IT UP
thread.interrupt( );

thread.join( );

// At this point, it is guaranteed that the thread has finished

Upvotes: 2

Related Questions