首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程问题- java.util.concurrent -可运行/可调用

线程问题- java.util.concurrent -可运行/可调用
EN

Stack Overflow用户
提问于 2012-03-15 13:03:01
回答 1查看 980关注 0票数 0

好吧,我要承认我对Java中的线程是个新手,我已经读了很多关于java.util.concurrent的文章,我有几个问题,我希望一个真人能回答。

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

我好奇的是我所做的是不是线程安全的。我已经扩展了ThreadPoolExecutor,所以我可以重写afterExecute方法,以便在Runnable完成线程中的工作后在Runnable中执行方法。据我所知,这个操作似乎是在主线程中完成的,并且被认为是线程安全的。

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

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

下面是一些代码来帮助解释:

扩展的ThreadPoolExecutor:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
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()的其他类:

代码语言:javascript
复制
public class someOtherClass {
    public SomeOtherClass(Runnable someRunnable) {
        someRunable.doSomething();
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-15 13:33:56

在看不到所有代码的情况下,无法说这么高级别的描述是“threadsafe”。据我们所知,您使用的架构中的“read”是一个阻塞操作,它将对您造成死锁!

通常,可以将一个资源或一个类描述为“threadsafe”,这意味着当它被多个线程使用时,它不会表现出不可预测的行为。但是,给定的资源是'threadsafe‘并不能保证当你尝试并行做一些事情时,你不会导致任何错误,如果所有这些事情都在一个线程上完成,这些事情就不会发生。只是行为是可预测的(对于任何给定的计时集,当然这些计时本身都是不可预测的)。

'threadsafe‘也不能说明某些东西确实适合高并发使用。一个完全同步的ArrayList是“线程安全”的,但是你肯定不想编写一个在大量线程之间共享它的程序,这些线程经常使用它!

我将尝试回答您的实际问题!:

首先,我创建了ThreadPoolExecutor和BlockQueue来帮助运行我的Runnable/Callable方法。为了用我有限的知识保持简单,我将所有活动限制为只读,不修改传递到Runnable中的任何对象

这看起来像是一个明显错误的陈述。如果你的runnable做了任何事情,你正在阅读的东西一定是要去什么地方。那个地方一定是runnable引用的东西。您需要分析的是您正在推送读取结果的资源是如何响应并发访问的。这就是潜在的危险所在。

Runnable我已经扩展了ThreadPoolExecutor,所以我可以重写afterExecute方法,以便在Runnable完成线程中的工作后在Runnable中执行方法。据我所知,这个操作似乎是在主线程中完成的,并且被认为是线程安全的。

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

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

是的,它将在调用方法的线程中运行,而不是在池线程中运行。“安全”是我们不能仅仅从体系结构描述(以及对安全的公认定义)开始判断的东西:)。

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

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9714275

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档