【问题标题】:Java: reference to non-finial local variables inside a thread [closed]Java:引用线程内的非最终局部变量[关闭]
【发布时间】:2016-01-01 00:00:51
【问题描述】:

我正在创建一些 Java 代码,如下所示:

new Thread() {
    @Override public void run() {
        for(;;) {
            DataPkg data_pkg = new DataPkg(datapkg_passport, new Data);
            try{
                int len = channel.read(data_pkg); //block read from the channel
                if (len > 0) writeWs(data_pkg);
                if (len == -1) {
                    channel.close();
                    writeWs(new SigPkg(sigpkg_passport, "201")); //channel termination notification
                    break;
                }
            } catch(Exception e) {e.printStackTrace();}
        }
        Thread.interrupted();
    }
}.start();

...但是编译器给了我一个错误:“从内部类引用的局部变量必须是最终的或有效的最终”。我知道类似的问题在网络上甚至在这里都被一次又一次地提出,但我只是没有找到一个好的答案。

我认为这是因为 VM 需要确保线程不应该使用由最近可能终止的方法动态创建的任何变量,并且对内存位置的引用变得无效并导致问题。

但在我的情况下,我确实需要在新创建的通道上设置一个专用线程来保持从通道的对等端提供数据并反馈到服务器端,并且该通道非常适合动态创建,因为它是不是一个简单的套接字。

对于这种情况有什么解决方案或变通方法吗?

【问题讨论】:

  • 请发帖MVCE,以便我们确切地查看问题所在。
  • 由于线程在一个新创建的频道上,并且出于它的目的只有一个活动频道,频道最终的问题是什么?
  • 听起来你应该在这里实现生产者-消费者模式......
  • 您没有修改您发布的代码中的任何变量。该错误发生在哪一行?
  • @Untitled123,您好我实际上可以在线程内创建通道,但是对于构造,它需要一些其他动态生成的变量(因为它不仅仅是一个套接字)并且问题反弹了。 ..(data_pkg 和 sig_pkg 的生成也一样...

标签: java multithreading local-variables


【解决方案1】:

使用构造函数使线程类非匿名(即声明一个静态类),并在实例化它时传入通道。

class MyThread extends Thread {
    private Channel channel;
    public MyThread(Channel channel) { this.channel = channel; }
    @Override public void run() { ... }
}

MyThread t = new MyThread(channel);
t.start();

【讨论】:

  • 谢谢吉姆,我认为这会锻炼身体,尽管我仍在尝试实现整体,因为逻辑变得有点复杂。
  • 太棒了!请“接受”这个更新,以便其他人知道它是正确的。
  • 嗨,吉姆,我没有在此页面上找到“接受”按钮或链接,请您提供建议,谢谢。
  • @GuZhang 就像答案右侧的复选标记。你可以点击它,它会变成绿色,这表明这个答案解决了你的问题。
【解决方案2】:

也许你在某处修改了channel?那会导致这个错误。只要确保每个线程都获得一个新的channel 变量。一种方法是在代码周围放置一对额外的大括号并在其中声明变量。还要将channel 设为final,这样编译器会告诉您是否尝试在某处修改它。

{
    final Channel channel = ...
    new Thread() {
        ...
    }.start();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 2023-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多