簡體   English   中英

Lambda表達式(NetBeans IDE)中的“在構造函數中啟動新線程”警告

[英]“Starting new Thread in constructor” warning in Lambda expression (NetBeans IDE)

當我在傳統的構造函數中啟動新線程時,NetBeansIDE不給出警告:

addActionListener(new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent e) {

        (new SomeThread()).start();
    }
});

但是,如果將其轉換為Lambda表達式,則會收到警告“在構造函數中啟動新線程”:

addActionListener((ActionEvent e) -> {

   (new SomeThread()).start();
});

這里有什么問題? 什么是正確的解決方案?

編輯1:

NetBeans IDE 8.0.2上的相同問題:

在此處輸入圖片說明

編碼:

import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class TimerClass extends Timer {

    public TimerClass() {
        super(1000, null);//Loop 1 sec

        addActionListener((ActionEvent e) -> {

            (new SomeClass()).start();
        });

    }

    private class SomeClass extends Thread {

        @Override
        public void run() {

        }
    }
}

這里的問題是啟動線程甚至在構造函數中注冊偵聽器都被認為是危險的。

說明:
內部類包含對其封閉類的引用,這TimerClass在構造函數返回之前,在構造函數中啟動的線程具有對TimerClass對象狀態的引用。 因此,新線程可能會看到帶有過期值(一個線程中是當前值,而其他線程中不是當前值)的部分構造的對象。

一個簡單的解決方法:
將構造函數設為私有,然后使公共靜態工廠方法創建對象並啟動線程。

import java.awt.event.ActionEvent;
import javax.swing.Timer;

public class TimerClass extends Timer {

    // notice that the constructor is now private.
    private TimerClass() {
        super(1000, null);  //Loop 1 sec
    }

    // This will create the instance and then register the listener and start the thread
    public static TimerClass createInstance() {

        TimerClass instance = new TimerClass();       
        instance.addActionListener((ActionEvent e) -> {

            (instance.new SomeClass()).start();
        });

        return instance;
    }

    private class SomeClass extends Thread {

        @Override
        public void run() {

        }
    }
}

這樣,線程將看到一個完全構造的對象,並且線程安全性將得以恢復(從而刪除警告)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM