Java集合类中的非线程安全在Collections工具类中的线程安全实现

我们都知道,Java中常用的集合框架中的实现类HashSet、TreeSet、ArrayList、ArrayDeque、LinkedList、HashMap、TreeMap都是线程不安全的,如果有多个线程同时访问它们,且同时有多个线程修改他们的时候,将会出现如读脏数据等错误。Collections提供了synchronizedXxx()方法来帮助其实现线程安全。下面给出代码演示:

import java.util.ArrayList;

import java.util.Collection;

import java.util.Collections;

import java.util.HashMap;

import java.util.HashSet;

import java.util.List;

import java.util.Map;

import java.util.Set;

public class TestSynchronized {

 static Collection cl = Collections

   .synchronizedCollection(new ArrayList());

 static List list = Collections

   .synchronizedList(new ArrayList());

 static Set set = Collections.synchronizedSet(new HashSet());

 static Map map = Collections

   .synchronizedMap(new HashMap());

 static boolean run = true;

 

 public static void main(String[] args) {

  // TODO Auto-generated method stub

  Thread a = new Thread(new Runnable() {

   @Override

   public void run() {

    System.out.println("*******This is a thread********");

    System.out.println("Is Collection add element successfully? "

      + (cl.add("lan") ? "Yes" : "No"));

    System.out.println("Is List add element successfully? "

      + (list.add(33) ? "Yes" : "No"));

    System.out.println("Is Set add element successfully? "

      + (set.add("lan") ? "Yes" : "No"));

    System.out

      .println("Map put element successfully. The element value is:"

        + map.put("lan", 33));

   }

  });

  Thread b = new Thread(new Runnable() {

   @Override

   public void run() {

    System.out.println("*******This is b thread********");

    System.out.println("Is Collection add element successfully? "

      + (cl.add("lan") ? "Yes" : "No"));

    System.out.println("Is List add element successfully? "

      + (list.add(33) ? "Yes" : "No"));

    System.out.println("Is Set add element successfully? "

      + (set.add("lan") ? "Yes" : "No"));

    System.out

      .println("Map put element successfully. The element value is:"

        + map.put("lan", 33));

   }

  });

  Thread c = new Thread(new Runnable() {

   @Override

   public void run() {

    System.out.println("*******This is c thread********");

    System.out.println("Is Collection add element successfully? "

      + (cl.add("lan") ? "Yes" : "No"));

    System.out.println("Is List add element successfully? "

      + (list.add(33) ? "Yes" : "No"));

    System.out.println("Is Set add element successfully? "

      + (set.add("lan") ? "Yes" : "No"));

    System.out

      .println("Map put element successfully. The element value is:"

        + map.put("lan", 33));

   }

  });

  a.start();

  b.start();

  c.start();

  Thread d = new Thread(new Runnable() {

   @Override

   public void run() {

    System.out.println("cl----->" + cl);

    System.out.println("list----->" + list);

    System.out.println("set----->" + set);

    System.out.println("map----->" + map);

   }

  });

  while (run) {

   if ((!a.isAlive()) && (!b.isAlive()) && (!c.isAlive())) {

    if (!d.isAlive()){

     run = false;

     d.start();

    }

   }

  }

 }

}

运行结果:

*******This is a thread********

Is Collection add element successfully? Yes

Is List add element successfully? Yes

Is Set add element successfully? Yes

Map put element successfully. The element value is:null

*******This is c thread********

Is Collection add element successfully? Yes

Is List add element successfully? Yes

Is Set add element successfully? No

Map put element successfully. The element value is:33

*******This is b thread********

Is Collection add element successfully? Yes

Is List add element successfully? Yes

Is Set add element successfully? No

Map put element successfully. The element value is:33

cl----->[lan, lan, lan]

list----->[33, 33, 33]

set----->[lan]

map----->{lan=33}

由此可以看出,无论线程如何修改资源,我们将得到最新的值,不会出现读脏数据。


你可能感兴趣的:(Java集合类中的非线程安全在Collections工具类中的线程安全实现)