※集合
System.out.println("synchronized list");
List<Integer> l = new ArrayList<>();
synchronized (l) {
l.add(1);
l.add(2);
l.add(3);
}
for (Integer i : l) {
System.out.println(i);
}
System.out.println();
System.out.println("synchronizedCollection");
Collection<String> c = Collections.synchronizedCollection(new ArrayList<>());
c.add("A");
c.add("B");
c.add("C");
synchronized (c) {
for (String s : c) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedList");
List<String> list = Collections.synchronizedList(new ArrayList<>());
list.add("D");
list.add("E");
list.add("F");
synchronized (list) {
for (String s : list) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedSet");
Set<String> set = Collections.synchronizedSet(new HashSet<>());
set.add("G");
set.add("H");
set.add("G");
synchronized (set) {
for (String s : set) {
System.out.println(s);
}
}
System.out.println();
System.out.println("synchronizedMap");
Map<Integer, String> map = Collections.synchronizedMap(new HashMap<>());
map.put(0, "A");
map.put(1, "B");
map.put(2, "C");
for (int i = 0; i < map.size(); i++) {
System.out.println(map.get(i));
}
※這些是 java 1.5 之前的寫法,for 迴圈有用 synchronized ,是因為使用到 Iterator ,它並不是 Thread-safe,而 for each 會用到 Iterator 物件,但最原始的 for 迴圈不會用到
※ java 1.5 集合
System.out.println("CopyOnWriteArrayList");
List<String> list = new CopyOnWriteArrayList<>();
list.add("D");
list.add("E");
list.add("F");
for (String s : list) {
System.out.println(s);
}
System.out.println();
System.out.println("CopyOnWriteArraySet");
Set<String> set = new CopyOnWriteArraySet<>();
set.add("G");
set.add("H");
set.add("G");
for (String s : set) {
System.out.println(s);
}
System.out.println();
System.out.println("ConcurrentHashMap");
Map<Integer, String> map = new ConcurrentHashMap<>();
map.put(0, "A");
map.put(1, "B");
map.put(2, "C");
for (int i = 0; i < map.size(); i++) {
System.out.println(map.get(i));
}
※java 1.5 新增了 java.util.concurrent 這個套件
※ThreadLocal
ThreadLocal 是 Thread 變數,在寫 Thread-safe 是很困難的,要讓 Thread 共用,又要同步,又有效能的問題,還要小心 Dead Lock,所以有人想到不要共用了,直接創造 Thread 的複本,在 java 1.2 就產生了 ThreadLocal 類別了,但此方法會需要較多的記憶體※
public class ThreadTest extends Thread {
private static int number;
public int getNumber() {
number = number + 1;
return number;
}
// private static ThreadLocal<Integer> number = new ThreadLocal<Integer>() {
// @Override
// protected Integer initialValue() {
// return 0;
// }
// };
// public int getNumber() {
// number.set(number.get() + 1);
// return number.get();
// }
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + "=" + getNumber());
}
}
public static void main(String... a) {
ThreadTest t1 = new ThreadTest();
ThreadTest t2 = new ThreadTest();
ThreadTest t3 = new ThreadTest();
t1.start();
t2.start();
t3.start();
}
}
※結果:
Thread-0=1
Thread-0=4
Thread-0=5
Thread-1=3
Thread-1=6
Thread-1=7
Thread-2=2
Thread-2=8
Thread-2=9
可以看得出來 Thread 之間被影響了,應該三個 Thread 都是 123 才是正確的
※打開註解並註解原來的 number 和 getNumber(),結果如下:
Thread-0=1
Thread-0=2
Thread-0=3
Thread-2=1
Thread-2=2
Thread-2=3
Thread-1=1
Thread-1=2
Thread-1=3
沒有留言:
張貼留言