线程问题 - java.util.concurrent - Runnable / Callable

时间:2012-03-15 05:03:01

标签: java concurrency

好的,我将承认自己刚接触Java中的线程,我一直在做很多关于java.util.concurrent的阅读,我有一些问题,我希望一个真人可以回答。

首先,我创建了ThreadPoolExecutor和BlockQueue来帮助运行我的Runnable / Callable方法。为了使我的有限知识保持简单,我将所有活动限制为只读,没有修改传递给Runnable的对象,并且创建的信息是从应用程序用来填充GUI表的数据库中提取的,任何信息都在数据库可以在收到之前或之后进行更改,与显示目的无关。

我很好奇的是,我所做的是线程安全的。我已经扩展了ThreadPoolExecutor,所以我可以覆盖afterExecute方法,在Runnable完成其在线程中的工作后执行该方法。从我所看到的,似乎这个操作是在主线程中完成的,并且被认为是线程安全的。

同样继续这个想法,如果我写另一个也在这个Runnable / Callable类中的方法并直接使用它而不使用run(或ThreadPoolExecutor.execute())它也会在主线程上运行注意安全。问题二:如果我在Runnable类的run()方法中使用此方法,它是否在线程上运行? (我假设它是,并要求确认)和如果我直接运行这个方法,它会在主线程上运行吗?

原因是我希望在一个类中保留与查询/更新/插入有关的所有内容,但在主线程中保留对数据库的更新。

一些代码可以帮助解释:

扩展的ThreadPoolExecutor:

public class DatabaseThreadPoolExecutor extends ThreadPoolExecutor {
    public DatabaseThreadPool(int corePoolSize, int maximumPoolSize, long keepAlive, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
        super(//pass info to super)
    }

    protected void afterExecute(Runnable runnable, Throwable throwable) {
        if(runnable instanceof someRunnable) {
            ((SomeRunnable) runnable).afterExecution();
        }
    }
}

Runnable类:

public class someRunable implements Runable {

    public someRunnable() {
        // used code withing thread
    }

    public doAfterExecute() {
        // run by ThreadPoolExecutor .afterExecute()
    }

    public doSomething() {
        // Run by someRunnable in thread
        // Also run directly by some other class
    }
}

其他一些调用doSomething()的类:

public class someOtherClass {
    public SomeOtherClass(Runnable someRunnable) {
        someRunable.doSomething();
    }
}

1 个答案:

答案 0 :(得分:1)

在没有看到所有代码的情况下,没有办法说这种高级描述是'线程安全的'。就我们所知,你所使用的架构中,“读取”是一种阻塞操作,它会对你造成死锁!

通常,人们可以将资源或类描述为“线程安全”,这意味着当多个线程使用它时,它不会表现出不可预测的行为。但是,给定的资源“线程安全”并不是一种认证,当你尝试并行执行时,如果在一个线程上完成所有这些操作,就不会导致任何错误。只是行为是可预测的(对于任何给定的时间集,当然这些时间本身是不可预测的)。

“线程安全”并不表示某些内容实际上适合高度并发使用。一个完全同步的ArrayList是'threadsafe',但你当然不希望编写一个程序,在许多经常使用它的线程中共享它!

尽管会尝试回答你的实际问题!:

  

首先,我创建了ThreadPoolExecutor和BlockQueue来帮助运行我的   Runnable / Callable方法。用我的限制来保持简单   knownledge我将所有活动限制为只读,没有通过对象   进入Runnable被修改

这似乎是一个明显错误的陈述。如果你的runnable做任何事情,你正在阅读的东西必须去某个地方。那个地方必须是runnable引用的东西。 您正在推动读取结果的资源如何响应并发访问是您需要分析的。这就是潜在危险所在。

  

我已经扩展了ThreadPoolExecutor,所以我可以覆盖afterExecute   完成后在Runnable中执行方法的方法   它在线程中的工作。从我所看到的,似乎这个   操作在主线程中完成,并被视为线程   安全

不,将在runnable上调用run()方法的同一个池线程中调用afterExecute()。不在提交Runnable的线程中。 “This method is invoked by the thread that executed the task

  

如果我写另一种方法,也继续这个想法   也可以在这个Runnable / Callable类中直接使用它   使用run(或ThreadPoolExecutor.execute())它也会   在主线程上运行并且是安全的。

是的,它将在您调用方法的线程中运行,而不是在池线程中运行。 “安全”是我们无法从架构描述(以及商定的安全定义)开始讲述的事情:)。

  

问题二:如果我从run()方法中使用此方法   Runnable类是在线程上运行的吗? (我认为是,并要求   确认)

是的,您在run()方法中调用的任何内容都将由执行任务的池线程执行。