为了账号安全,请及时绑定邮箱和手机立即绑定

创建线程后创建对象与创建线程时传递对象

创建线程后创建对象与创建线程时传递对象

皈依舞 2021-12-30 17:21:55
创建线程后创建对象(下面的方法 A)与在当前线程中创建对象并将其传递给新线程(方法 B)之间有什么区别吗?方法一:public class AppA {    private A app;    public void run() {        Runnable runnable = () -> {            this.app = new A();        };        Thread workerA = new Thread(runnable);        workerA.start();    }}public class A {    private final EventDispatcher dispatcher;    A() {        this.dispatcher = new EventDispatcher();    }}public static void main(String[] args) {    AppA appA = new AppA();    appA.run();}方法B:public class AppB {    private B app;    public void run() {        EventDispatcher dispatcher = new EventDispatcher();        Runnable runnable = () -> {            this.app = new B(dispatcher);        };        Thread workerB = new Thread(runnable);        workerB.start();    }}public class B {    private final EventDispatcher dispatcher;    B(EventDispatcher dispatcher) {        if (dispatcher == null) {            throw new NullPointerException();        }        this.dispatcher = dispatcher;    }}public static void main(String[] args) {    AppB appB = new AppB();    appB.run();}App 在单线程中创建的对象。app.run() 从单线程调用。
查看完整描述

3 回答

?
鸿蒙传说

TA贡献1865条经验 获得超7个赞

我相信如果您不将相同的对象用于其他用途(可能将其传递给不同的线程),则没有区别。这就像基本的 OOP - 你应该在你将使用它的最窄范围内定义你的对象。作为一个线程没有区别。所以如果你想在线程之外使用它 - 在外面创建它。否则在线程中创建它。


查看完整回答
反对 回复 2021-12-30
?
忽然笑

TA贡献1806条经验 获得超5个赞

这主要是一个品味问题。但是在方法中A,您有更好的封装。如果您不需要访问线程外的调度程序,则最好内联创建它。但是,如果您确实需要访问权限,或者您创建了需要单个调度程序的多个线程,则通过构造函数注入它会更好。

因此:这取决于...


查看完整回答
反对 回复 2021-12-30
?
慕码人2483693

TA贡献1860条经验 获得超9个赞

在这个例子中,差异纯粹是风格上的。但我认为 A 版更好,因为:

  • 版本A更简单

  • 传递给构造函数(在版本 B 中)的对象AppB在您创建它的类中没有使用/需要......所以版本 B 中的额外复杂性没有真正的目的。

但是,假设你需要从父线程参数传递给子线程通过Runnable,那绝对是好做它的版本B的方式比其他方式。

例如,假设您想从主线程传递一个StringBuilder1到子线程:

  • 版本 B 方法不需要执行任何同步来实现传输。在父线程中调用 to和子线程中相应调用 to之间有一个happens-before。这确保子线程将看到2Thread.start()Runnable.run()StringBuilder

  • 如果 对Runnable父线程执行回调以获取在StringBuilder之后由父线程创建的潜在对象start(),则需要使用某种形式的同步;例如同步方法。

  • 如果父线程要StringBuilderstart()调用之后主动传递(例如通过在Runnable对象上调用 setter ),那么您需要同步和某种协调;例如,子线程可能需要等待传递给它的对象。


1 - 本示例选择此类,因为它不是线程安全的。

2 - 这假设“主”线程在调用后不会更改缓冲区start()


查看完整回答
反对 回复 2021-12-30
  • 3 回答
  • 0 关注
  • 223 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号