Asked  7 Months ago    Answers:  5   Viewed   37 times

In ArrayBlockingQueue, all the methods that require the lock copy it to a local final variable before calling lock().

public boolean offer(E e) {
    if (e == null) throw new NullPointerException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        if (count == items.length)
            return false;
        else {
            insert(e);
            return true;
        }
    } finally {
        lock.unlock();
    }
}

Is there any reason to copy this.lock to a local variable lock when the field this.lock is final?

Additionally, it also uses a local copy of E[] before acting on it:

private E extract() {
    final E[] items = this.items;
    E x = items[takeIndex];
    items[takeIndex] = null;
    takeIndex = inc(takeIndex);
    --count;
    notFull.signal();
    return x;
}

Is there any reason for copying a final field to a local final variable?

 Answers

12

It's an extreme optimization Doug Lea, the author of the class, likes to use. Here's a post on a recent thread on the core-libs-dev mailing list about this exact subject which answers your question pretty well.

from the post:

...copying to locals produces the smallest bytecode, and for low-level code it's nice to write code that's a little closer to the machine

Tuesday, June 1, 2021
 
wavyGravy
answered 7 Months ago
97

When the onCreate() method returns, your local variable will be cleaned up from the stack, so they won't exist anymore. But the anonymous class object new View.OnClickListener() references these variables. Of cause it's wrong behavior so java don't allow you to do this.

After it is final it becomes a constant. So it is storing in the heap and can be safely used in anonymous classes.

Wednesday, July 28, 2021
 
Eugenie
answered 5 Months ago
76

Basically it just means you can't change the value. For instance variables, you have to assign any final variables once (and only once) in the constructor (or with a variable initializer). Synchronization is a pretty orthogonal concept.

The primary reason for making a local variable final is so you can use it in an anonymous inner class... this has nothing to do with being in a synchronized block.

Final variables are useful for immutable classes, admittedly - and immutability makes life easier in a multi-threaded environment - but that's the only relationship between the two that I can think of...

EDIT: Wildwezyr's comment makes sense in terms of not changing the variable on which you are synchronizing. That would be dangerous, for the reasons he's given. Is that what you meant by "variable in synchronized block"?

Saturday, August 14, 2021
 
StoneThrow
answered 4 Months ago
29

You can simply create an inner class instead of an anonymous one (like you are currently doing). Then you have a constructor and any other methods you want to set your members. No hackiness required (like the array of 1 case).

I find this cleaner if the class requires any exchange of data with its outer class, but admit it is a personal preference. The array of 1 idiom will work as well and is more terse, but frankly, it just looks fugly. I typically limit anonymous inner classes to those that just perform actions without trying to update data in the outer class.

For example:

private MyListener listener = new MyListener();

void onStart(){
  bt.setOnClickListener(listener);
}

class MyListener implements OnClickListener
{ 
    String name;
    int value;

    void setName(String newName)
    {
        name = newName;
    }

    void setValue(int newValue)
    {
        value = newValue;
    }

    public void onClick(View v) 
    {
        // Use the data for some unknown purpose
    }
}

If there are multiple threads involved, then appropriate synchronization will have to be used as well.

Wednesday, September 29, 2021
 
noir
answered 2 Months ago
49

JIT will change (optimize) your code on runtime, so this is not important in Java. One simple JIT optimization is method inlining.

For further optimization read about Micro Benchmarking and look at this question How do I write a correct micro-benchmark in Java?

Monday, October 4, 2021
 
Daveel
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share