线程的方法调用没有完成 - 如何结束线程 - 解决方法

时间:2014-06-12 20:00:24

标签: java multithreading swing locking signals

我有以下代码。

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();
}

当线程调用方法someMethod()时,它会被执行。但是因为该函数有一个await()方法。它永远不会结束/它不会打印'This never prints',除非它被singnalAll()唤醒。但我希望线程在执行后完成。

我无法重构整个事情。我只需要解决这个问题。它用于Swing应用程序。所以线程很重要。

3 个答案:

答案 0 :(得分:2)

我想,这样做:

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

答案 1 :(得分:1)

我不确定我是否正确理解了你的问题,但我认为你想启动someMethod()函数,然后让调用者退出而不等待someMethod()完成。这意味着你基本上将你的执行流程分支为两个,其中someMethod()运行等待它的到期唤醒,另一个是调用者继续运行(如果你想让它完成它需要做的话),在调用someMethod之后()。为此,您必须在单独的线程中运行someMethod()。这样的事情。

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();
}

答案 2 :(得分:1)

您可以通过两种方式对此进行排序。

1)使用中断政策设计您的任务

做一个防御性的编码。如果您的任务被任何方式中断,程序应该知道如何处理。

2)在此example中添加一个毒药丸,一旦

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

根据实践中的每个Java并发

使用条件等待时(Object.wait或Condition.await):

1)总是有一个条件谓词对象状态的一些必须保持的测试 程序;

2)始终在调用wait之前测试条件谓词,并在返回之后再次测试 等待;

3)总是在循环中调用wait;

4)确保构成条件谓词的状态变量受到锁的保护 与条件队列相关联;

5)在调用wait,notify或时,保持与条件队列关联的锁 notifyAll的;和

6)在检查条件谓词之后但在采取行动之前不要释放锁。