スレッドが独自のコンストラクタ内でthis.start()を呼び出すことは正当ですか?もしあれば、これによって起こりうる潜在的な問題は何か?コンストラクタが完了するまでオブジェクトが完全に初期化されていないことを理解していますが、これ以外にも問題はありますか?独自のコンストラクタ内でthread.start()を呼び出す
答えて
これは合法ですが、賢明ではありません。インスタンスのスレッド部分は完全に初期化されますが、コンストラクタは初期化されません。スレッドを拡張する理由はほとんどなく、このような手口を引き出すことはあなたのコードを助けるものではありません。
私はあなたのコードをあまり冗長にしたくないと思います。代わりに、あなただけの
activeThreads.add(new CustomThread());
を言うことができ
Thread t = new CustomThread();
t.start();
activeThreads.add(t);
を言って、私はまた、より少ない冗長性を持っているような、私はあなたがこれを行うべきではない、他の回答に同意します。具体的には、それは規約を破る。 2番目の例を読んでいるJavaに精通している人は、スレッドが開始されていないと仮定します。さらに悪いことに、あなたと何らかの形で相互作用する独自のスレッドコードを書くと、スレッドによってはstart
を呼び出す必要があり、他のスレッドは呼び出されません。
自分で作業しているときにはこれは魅力的ではないかもしれませんが、最終的には他の人とやりとりする必要があります。他の人と一緒に仕事をしたり、標準的な規則で書かれたコード
しかし、慣習を気にかけず、特別な冗長さを嫌うならば、先に進んでください。誤ってstart
に複数回電話をかけようとしても、問題はありません。 1は、下の冗長性を望んでいるし、まだその「標準」の意味で、コンストラクタを続けるならば、1はファクトリメソッドを作成することができところで
、:
activeThreads.add(CustomThread.newStartedThread());
それはは「法的」ですが、私は考えます最も重要な問題は次のとおりです。 クラスは1つのことを行い、それをうまくやる必要があります。
クラスがスレッドを内部的に使用する場合は、そのスレッドの存在をパブリックAPIで表示しないでください。これにより、パブリックAPIに影響を与えずに改善が可能です。解決策:ThreadではなくRunnableを拡張します。
このクラスではスレッドで実行される一般的な機能を提供するクラスの場合は、に常ににスレッドを作成することを制限したくありません。ここで同じ解決策:スレッドではなく、Runnableを拡張する。
あまり冗長ではないため、ファクトリメソッド(Foo.createAndRunInThread()など)を使用することをおすすめします。
メモリの安全性の理由から、オブジェクトまたはそのオブジェクトのフィールドへの参照を、そのコンストラクタ内の別のスレッドに公開しないでください。カスタムスレッドにインスタンス変数があると仮定すると、コンストラクタ内からインスタンス変数を開始することによって、Javaメモリモデルのガイドラインに違反することが保証されます。詳細はBrian Goetz's Safe Construction Techniquesを参照してください。
この回答にコメントしますか?間違っているわけではありません。 –
Downvote?これが間違っていると思われる場合は、サイトをソースしてください。これは正しいです。 –
答えはまったくできません。 Runnableコンストラクタを使用しない限り、コンストラクタが完了する前に 'Thread#run'の中から' this'を参照することができます。これはメモリ安全ルールに違反します。したがって、あなたは注意する必要があります。 –
さらに、スレッドクラスがさらにサブクラス化されている場合には、厄介な問題が発生します。その場合、super()が終了すると既にスレッドが実行されてしまい、そのサブクラスがそのコンストラクタで行うことができるものが無効になる可能性があります。
@bill barksdale スレッドがすでに実行されている場合、startを再度呼び出すと、IllegalThreadStateExceptionが発生します.2つのスレッドがありません。
法律...はい(他のところで言及されているように注意してください)。お勧めです...いいえ。
私はちょうどあなたがあまりにも簡単に避けることができる匂いです。あなたのスレッドを自動起動させたい場合は、Heinz Kabutzのようにしてください。
public class ThreadCreationTest {
public static void main(String[] args) throws InterruptedException {
final AtomicInteger threads_created = new AtomicInteger(0);
while (true) {
final CountDownLatch latch = new CountDownLatch(1);
new Thread() {
{ start(); } // <--- Like this ... sweet and simple.
public void run() {
latch.countDown();
synchronized (this) {
System.out.println("threads created: " +
threads_created.incrementAndGet());
try {
wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
};
latch.await();
}
}
}
- 1. コンストラクタ内でoncreateを呼び出す
- 2. コンストラクタでクラスメンバのコンストラクタを呼び出す
- 3. 子コンストラクタ内で親コンストラクタを呼び出す
- 4. 独自のクラスでインタフェースメソッドを呼び出す方法は?
- 5. Cで独自のイベントコードとカスタムイベントコードを呼び出す
- 6. 同じコンストラクタ内でのコンストラクタの呼び出し
- 7. 内部クラス内でoutterクラスのコンストラクタを呼び出す方法
- 8. コンストラクタでのコンストラクタの呼び出し
- 9. 独自のクラス内で静的関数を呼び出せません
- 10. コンストラクタを呼び出さずにクラス内のメソッドを呼び出す
- 11. typescript内のコンストラクタ()内でsuper()を呼び出せません
- 12. コンストラクタ呼び出し
- 13. .NETサービスホストが独自のサービスを呼び出す
- 14. ディスパッチロボットが独自のコマンドを呼び出す方法
- 15. prototype.js Ajax.PeriodicalUpdater独自の関数を呼び出す
- 16. インラインCアセンブリが独自の変数を呼び出す
- 17. 独自のjavacriptライブラリを作成して呼び出す
- 18. 各メソッド呼び出しでjQueryがコンストラクタを呼び出す
- 19. defrecordコンストラクタで呼び出しを呼び出しますか?
- 20. 派生クラスのコンストラクタの内部で基本クラスのコンストラクタを呼び出すC++
- 21. 新しいスレッドを内部で呼び出すのがコンストラクタ
- 22. 他のコンストラクタ内でコピーコンストラクタを呼び出す
- 23. クラス内でグローバルな別のコンストラクタを呼び出す
- 24. run()はThread.start()メソッドによって呼び出されません
- 25. コンストラクタとライフサイクルメソッドの呼び出しを呼び出す
- 26. コンストラクタの呼び出しメソッド
- 27. エラー:コンストラクタの呼び出し
- 28. C++コンストラクタの呼び出し -
- 29. Javaコンストラクタの呼び出し
- 30. コンストラクタでsuper()を呼び出す理由
これはOPの質問とどのように関連していますか? – subsub