My question is why I should use final to decorate the variable, list? It is used by the instance of an anonymous inner class Without final, it won't compile.
the code looks like this:
public class TwoThreadsOneListCurrModi
{
public static void main(String[] args)
{
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
for (int i =0 ; i<20;i++)
list.add(String.valueOf(i));
Thread t1 = new Thread(new Runnable(){
@Override
public void run()
{
synchronize(list) {
System.out.println("size of list:" +list.size());
}
}
});
t1.start();
}
}
But if I use normal class, it is fine.
public class TwoThreadsOneListCurrModi2
{
public static void main(String[] args)
{
final List<String> list = Collections.synchronizedList(new ArrayList<String>());
initialize list;
Thread t1 = new WorkThread(list);
Thread t2 = new WorkThread(list);
t1.start();
t2.start();
}
}
class WorkThread extends Thread{
List<String> list;
public void run(){
do sth with list and synchronize block on list
}
Work1(List<String> list)
{ this.list = list; }
}
This has nothing to do with multithreading. It is there because you are trying to access list from an anonymous inner class' method. Java will always sign an error in this case.
In your case you are creating an anonymous instance of Runnable here by using the new keyword. Everything you are trying to dereference from run will need to be final.
If you are curious about the necessity of the final keyword you can check Jon Skeet's exhaustive answer which explains it in depth.
The point is that when you create an instance of an anonymous inner class, any variables which are used within that class have their values copied in via the autogenerated constructor and it would look odd if the variable could be modified by the rest of the method and vica versa.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With