Retrologic Systems Retrologic Systems Retrologic Systems
RetroGuard for Java Obfuscation
  RetroGuard  |  CAPTCHA  |  Contracting  |  Resellers  |  Contact

Inner Classes Specification

Do inner classes affect the correct synchronization of Java code?

Note: This Inner Classes Specification is available for download as part of the JDK1.1 End Of Life (EOL) section of the Sun website. It has been included here because most of the specification is still relevant to the current Java classfile definition. However, the information has not been transferred into the latest Java Virtual Machine Specification or made available elsewhere in Sun's online Java resources.


Prev   Contents   Next

An inner class is part of the implementation of its enclosing class (or classes). As such, it has access to the private members of any enclosing class. This means that the programmer must be aware of the possibility of concurrent access to state stored in private variables, and ensure that non-private methods are correctly synchronized. Sometimes this just means that the enclosing method needs to be declared with the synchronized keyword.

When more than one object is involved, as with FixedStack and its enumerator, the programmer must choose which instance to synchronize upon, and write an explicit synchronized statement for the enclosing instance:


            public Object nextElement() {
                ...
                synchronized (FixedStack.this) {
                    return array[--count];
                }
            }

There is no special relation between the synchronized methods of an inner class and the enclosing instance. To synchronize on an enclosing instance, use an explicit synchronized statement.

When writing multi-threaded code, programmers must always be aware of potential asynchronous accesses to shared state variables. Anonymous inner classes make it extremely easy to create threads which share private fields or local variables. The programmer must take care either to synchronize access to these variables, or to make separate copies of them for each thread. For example, this for-loop needs to make copies of its index variable:


        for (int ii = 0; ii < getBinCount(); ii++) {
            final int i = ii; // capture a stable copy for each thread
            Runnable r = new Runnable() {
                public void run() { processBin(i); }
            };
            new Thread(r, "processBin("+i+")").start();
        }

It is a common mistake to try to use the loop index directly within the inner class body. Since the index is not final, the compiler reports an error.


Prev   Contents   Next
RetroGuard Newsletter
Your email address will be kept strictly confidential and never provided to third parties. Unsubscribe using the email address beneath each mailing.
 Copyright © 1998-2007 Retrologic Systems. retroguard | captcha | contracting | resellers | site map | contact
 All rights reserved. site terms | privacy policy