Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.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_Android_Multithreading_Constructor - Fatal编程技术网

Java 实例化一个类,然后在另一个线程中使用它

Java 实例化一个类,然后在另一个线程中使用它,java,android,multithreading,constructor,Java,Android,Multithreading,Constructor,考虑两个线程:threadA和threadB。(例如,让threadA成为UI线程,让threadB成为thread自己的子类)关于数据可见性,在threadA中实例化一个类,将其传递给threadB的构造函数,然后从threadB独占使用它是否安全?让我用代码来澄清这一点。(请注意,代码已简化,因此此体系结构在实际应用程序中的实际形式是有意义的。) 启动一切的方法如下(其位置无关)。这被称为threadA 我知道构造函数是不允许同步的,并且它内部不需要同步的代码(因为这个引用——除非泄漏出去—

考虑两个线程:threadA和threadB。(例如,让threadA成为UI线程,让threadB成为
thread
自己的子类)关于数据可见性,在threadA中实例化一个类,将其传递给threadB的构造函数,然后从threadB独占使用它是否安全?让我用代码来澄清这一点。(请注意,代码已简化,因此此体系结构在实际应用程序中的实际形式是有意义的。)

启动一切的方法如下(其位置无关)。这被称为threadA

我知道构造函数是不允许同步的,并且它内部不需要同步的代码(因为这个引用——除非泄漏出去——在类在其创建者线程中构造之前对其他线程不可用)。所以我的问题是关于数据可见性的:如果调用
threadB.start()
后我不从threadA访问
someClass
(及其任何引用的数据),那么代码是否安全


换句话说,
threadB.run()
是否会查看
someClass
数据的最新版本(例如字段、内部引用等)?我的猜测是:由于threadB第一次访问
someClass
后,
someClass
上不会有外部更改,threadB必须看到正确的值,因为它不能有以前的缓存副本。因此,出于上述原因,我不需要从
threadB.run()
访问同步块中的
someClass
。(再次注意,threadB启动后threadA不会访问
someClass

如果您是说,在
threadB.start()
之后,
someClass
引用的实例将不再被任何其他线程修改:是的,
threadB.run()
将看到最新版本


在这种情况下,实际上不存在可能发生的并发/竞争条件。每件事都是按顺序发生的,你只是有一些对象是
Thread
s,我想这可能会让你有点偏执:)。

ThreadA正在修改所讨论的对象,然后启动第二个线程:这里只有一个执行顺序。ThreadA创建对象,可能对其进行修改,将其交给ThreadB,可能对其进行更多修改,然后B启动。没有任何上下文切换或任何其他类似事件可以导致异常。@LuxuryMode:我看到cklab已经回答了,但不同的词是相同的:如果在调用threadB.start()之后调用someClass.foo=“bar”,那么您是对的,threadB可能会看到过期的副本。但在我的软件中,它确保了在调用threadB.start()后不会触动someClass。实际上,我的妄想是因为run()访问由另一个线程创建的数据。由于threadB是另一个线程,它可能缓存了这些数据的副本。但是,由于这是它第一次访问这些数据,它不能有缓存副本。多线程单进程程序中的所有线程共享相同的地址空间,因此您不必担心缓存。(谢天谢地,否则多线程将比现在更加困难!)
public class SomeClass {
    public SomeClass(....) {
       // initialization
    }
}

public class MyCustomThread extends Thread {
    public MyCustomThread(SomeClass someClass) {
        mSomeClass = someClass;
    }

    @Override
    public void run() {
           // operate on mSomeClass         
    }
}
public void launchThread() {
   SomeClass someClass = new SomeClass();
   MyCustomThread threadB = new MyCustomThread(someClass); // MyCustomThread is a subclass of Thread
   threadB.start();
   // After this point, threadA never accesses someClass,
   // and only threadB is operating on it
}