如何在可运行线程内分配值

时间:2019-05-07 13:20:35

标签: java multithreading

我有下一个代码:

    for(int i = 0; i < fileRefernces.size(); i++) { 
        Thread t = new Thread(new Runnable() {
                    public void run() {
                        JLabel pageNumber = new JLabel("<html><font color='#003b86'>PAGE" + (i + 1) + "</font></html>", JLabel.LEFT);
                        JLabel imageLabel = new JLabel(image, JLabel.LEFT);
                        // content would be probably some Image class or byte[]

                        // or:
                        // InputStream in = Loc.openStream();
                        // read image from in
                    }
                });
    }

但是,就在此刻分配值时,我得到了下一个错误:

  

错误:从内部类引用的局部变量必须是final或   有效地最终

如何为这些变量赋值?

2 个答案:

答案 0 :(得分:1)

  

错误:从内部类引用的局部变量必须是final或有效的final

此编译器错误正是您的问题,因为在Java中,正如编译错误所言,在lambda或内部类中使用的所有局部变量必须为 final或有效地为final

基本上,这意味着您无法使用在方法中定义的任何局部变量(内部类中的),除非它们是最终的/实际上是最终的。拿这个:

root.after

变量 public void someMethod() { int x = 5; Thread thread = new Thread(new Runnable() { public void run() { x = 4; // This is a compilation error. } }); thread.start(); } 实际上不是最终变量,因为该值在run方法内部已更改,因此无法使用。

现在接受这个:

x

还会导致编译错误,因为即使public void someMethod() { int x = 5; x = 4; Thread thread = new Thread(new Runnable() { public void run() { System.out.println(x); // This is a compilation error. } }); thread.start(); } 的值在运行方法之外 发生了更改,但由于该更改,它实际上不是最终的

以上两个示例均带有局部变量,这些局部变量实际上不是最终变量。现在,在这里:

x

此处public void someMethod() { int x = 5; final int y = 6; List<String> list = new ArrayList<>(); Thread thread = new Thread(new Runnable() { public void run() { System.out.println(x); System.out.println(y); list.add("String added in thread"); list.forEach(System.out::println); // Will print "String added in thread" } }); thread.start(); } xy都是有效的变量,可以在内部类中使用,因为它们都是有效的final 或< em>最终。

答案 1 :(得分:1)

使用局部最终变量,您只需实例化一次即可解决该问题。

final Image finalImage = image;
for(int i = 0; i < fileRefernces.size(); i++) { 
    final int finalCounter = i + 1;
    Thread t = new Thread(new Runnable() {
        public void run() {
            JLabel pageNumber = new JLabel("<html><font color='#003b86'>PAGE" + finalCounter + "</font></html>", JLabel.LEFT);
            JLabel imageLabel = new JLabel(finalImage, JLabel.LEFT);
            // commented code
        }
    });
}