Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建线程后创建对象与创建线程时传递对象_Java_Multithreading - Fatal编程技术网

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

Java 创建线程后创建对象与创建线程时传递对象,java,multithreading,Java,Multithreading,在线程创建之后创建对象(下面的方法A)和在当前线程中创建对象并将其传递给新线程(方法B)之间有什么区别吗 方法A: public class AppA { private A app; public void run() { Runnable runnable = () -> { this.app = new A(); }; Thread workerA = new Thread(runnable)

在线程创建之后创建对象(下面的方法A)和在当前线程中创建对象并将其传递给新线程(方法B)之间有什么区别吗

方法A:

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()
    从单个线程调用

我相信,如果您不将同一对象用于其他对象(可能会将其传递给不同的线程),则不会有任何区别。它类似于基本的OOP——您应该在最窄的范围内定义您的对象,您将在其中使用它。作为一根线没有区别。因此,如果您想在线程外部使用它,请在线程外部创建它。否则,在线程中创建它。

我相信如果不将同一个对象用于其他对象(可能会将其传递给不同的线程),则没有什么区别。它类似于基本的OOP——您应该在最窄的范围内定义您的对象,您将在其中使用它。作为一根线没有区别。因此,如果您想在线程外部使用它,请在线程外部创建它。否则,在线程中创建它。

这主要取决于味道。但是在方法
A
中,您有一个更好的封装。如果您不需要访问线程外的调度程序,则更倾向于内联创建它。 但是,如果您确实需要访问,或者您创建了多个线程,而这些线程需要一个调度器,那么通过构造函数注入它会更好


因此:这取决于……

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


因此:这取决于……

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

  • 版本A更简单
  • 正在传递给构造函数(在版本B中)的对象在创建它的类
    AppB
    中没有使用/需要。。。因此,版本B中额外的复杂性没有真正的目的
但是假设您需要通过
Runnable
将参数从父线程传递给子线程,那么使用版本B的方式肯定比其他方式更好

例如,假设要将
StringBuilder
1从主线程传递到子线程:

  • 版本B方法不需要执行任何同步来实现传输。在父线程中对
    Thread.start()
    的调用和子线程中对
    Runnable.run()
    的相应调用之间,会发生一个错误。这确保子线程将看到
    StringBuilder
    2的状态

  • 如果
    Runnable
    执行对父线程的回调,以拾取父线程在
    start()
    之后可能创建的
    StringBuilder
    ,则需要使用某种形式的同步;e、 g.同步方法

  • 如果父线程将在调用
    start()
    后主动传递
    StringBuilder
    (例如,通过调用
    Runnable
    对象上的setter),则需要同步和某种协调;e、 g.子线程可能需要等待对象传递给它


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


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

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

  • 版本A更简单
  • 正在传递给构造函数(在版本B中)的对象在创建它的类
    AppB
    中没有使用/需要。。。因此,版本B中额外的复杂性没有真正的目的
但是假设您需要通过
Runnable
将参数从父线程传递给子线程,那么使用版本B的方式肯定比其他方式更好

例如,假设要将
StringBuilder
1从主线程传递到子线程:

  • 版本B方法不需要执行任何同步来实现传输。在父线程中对
    Thread.start()
    的调用和子线程中对
    Runnable.run()
    的相应调用之间,会发生一个错误。这确保子线程将看到
    StringBuilder
    2的状态

  • 如果
    Runnable
    执行对父线程的回调,以拾取父线程在
    start()
    之后可能创建的
    StringBuilder
    ,则需要使用某种形式的同步;e、 g.同步方法

  • 如果父线程将在调用
    start()
    后主动传递
    StringBuilder
    (例如,通过调用
    Runnable
    对象上的setter),则需要同步和某种协调;e、 g.子线程可能需要等待对象传递给它


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

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