-1

I am creating some Java codes like the following:

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();

...but the compiler has given me an error: "local variables referenced from an inner class must be final or effectively final". I know similar questions been presented again and again on the web and even here, but I just did not find a good answer.

I think this is because the VM needs to make sure that the thread should not use any variable dynamically created by a method who may terminated lately and the reference to the memory location becomes invalid and causes problem.

But in my case I really need a dedicated thread on the newly created channel to keep feeding data from the peer side of the channel and feed back to the server side, and that channel is very preferred to be dynamically created since it is not a simple socket.

Is there any solution or work-around for this situation?

  • 2
    Please post an [MVCE](http://stackoverflow.com/help/mcve) so we can see *exactly* what the problem is. – erip Jan 01 '16 at 00:03
  • Since the thread is on a newly created channel, and for it's purposes there is only one active channel, what's the issue for channel being final? – Untitled123 Jan 01 '16 at 00:04
  • It almost sounds like you should be implementing the producer-consumer pattern here... – Roddy of the Frozen Peas Jan 01 '16 at 00:04
  • You are not modifying any variables in the code you posted. In what line is that error occurring? – Tesseract Jan 01 '16 at 00:08
  • @Untitled123, Hi I can actually make the channel being created inside the thread, but for construction, it needs some other dynamically generated variables (as it is not just a socket) and the problem bounced back... (the same for the generation of data_pkg and sig_pkg... – howToDeleteMyAccount Jan 01 '16 at 00:17

2 Answers2

1

Make the thread class non-anonymous (i.e. declare a static class) with a constructor and pass in the channel when you instantiate it.

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();
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
0

Maybe you modify channel somewhere? That would cause this error. Just make sure that each Thread gets a new channel variable. One way to do that is to put an extra pair of braces around the code and declare the variable inside. Also make channel final so the compiler will tell you if you try to modify it somewhere.

{
    final Channel channel = ...
    new Thread() {
        ...
    }.start();
}
Tesseract
  • 8,049
  • 2
  • 20
  • 37