Java Shell Shell Workaround

Today I found that using Collections.synchronizedXXX does not reflect very well.

Here is a simple example:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Weird{
  public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("Hello World");

    List<String> wrappedList = Collections.synchronizedList(list);

    printSizeUsingReflection(list);
    printSizeUsingReflection(wrappedList);
  }

  private static void printSizeUsingReflection(List<String> list) {
    try {
      System.out.println(
          "size = " + list.getClass().getMethod("size").invoke(list));
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

The first call to printSizeUsingReflection prints the size (ie "1"), the second call results in:

java.lang.IllegalAccessException: Class Weird can not access a member of class
    java.util.Collections$SynchronizedCollection with modifiers "public"
  at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:65)
  at java.lang.reflect.Method.invoke(Method.java:588)
  at Weird.printSizeUsingReflection(Weird.java:18)
  at Weird.main(Weird.java:13)

This is a bit surprising and annoying. Is there a good workaround? I know that in java.util.concurrent there is a threaded implementation of List, but this implementation looks slower than using Collections.synchronizedList ().

+5
source share
4 answers

The reason for the exception is that the class received by the call

list.getClass()

in line

System.out.println("size = " + list.getClass().getMethod("size").invoke(list));

- java.util.Collections $SynchronizedCollection. SynchronizedCollection Collections, , , .

- / - ( ), size() , obj.getClass() . , size() java.util.Collection() java.util.List.

"size = 1" :

System.out.println("size = " + Collection.class.getMethod("size").invoke(list));
System.out.println("size = " + List.class.getMethod("size").invoke(list));

, size(), , "", . size() - - Collection/List, size() SynchronizedCollection , . , .

, , - Collection size().

+5

Collection.class ( - ( ), - ). .

+3

java.util.Collections $SynchronizedCollection - .

+1

, java.util.concurrent (, , ?).

, 2 :

  • LinkedBlockingQueue
  • CopyOnWriteArrayList

, . , , java.util.concurrent .

Concurrent Collections "Java Concurrency In Practice":

CopyOnWriteArrayList is a parallel replacement for a synchronized list that offers better concurrency in some general situations and eliminates the need to lock or copy the collection during iteration. (By analogy, CopyOnWriteArraySet is a parallel replacement for synchronized dialing.)

0
source

All Articles