package JUC; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * @author zhaolimin * @date 2021/11/13 * @apiNote ArrayList类不安全测试 */ public class ArrayListNotSafeDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); }, String.valueOf(i)).start(); } // java.util.ConcurrentModificationException 出现了快速失败机制 } }
public static void main(String[] args) { List<String> list = new Vector<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); }, String.valueOf(i)).start(); } }
public static void main(String[] args) { List<String> list = Collections.synchronizedList(new ArrayList<>()); for (int i = 0; i < 50; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); }, String.valueOf(i)).start(); } }
public static void main(String[] args) { List<String> list = new CopyOnWriteArrayList<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { list.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(list); }, String.valueOf(i)).start(); } }
/** 追加一个特殊的元素到这个List集合的尾部。 */ public boolean add(E e) { // 用 ReentrantLock 加锁 final ReentrantLock lock = this.lock; lock.lock(); // 注:JDK9以后已经改为 synchronized 加锁了。 try { // 拿到旧表 Object[] elements = getArray(); // 拿到旧表的长度 int len = elements.length; // 在旧表的基础上拷贝并长度 + 1 新表 Object[] newElements = Arrays.copyOf(elements, len + 1); // 在新表的末尾追加要添加的元素 newElements[len] = e; // 将当前表设置为新表 setArray(newElements); // 返回添加成功 return true; } finally { // 解锁 lock.unlock(); } }
package JUC; import java.util.HashSet; import java.util.UUID; /** * @author zhaolimin * @date 2021/11/14 * @apiNote HashSet线程不安全测试。 */ public class HashSetNotSafeDemo { public static void main(String[] args) { HashSet<String> strings = new HashSet<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { strings.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(strings); }, String.valueOf(i)).start(); } } }
public static void main(String[] args) { Set<String> strings = Collections.synchronizedSet( new HashSet<>()); for (int i = 0; i < 50; i++) { new Thread(() -> { strings.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(strings); }, String.valueOf(i)).start(); } }
public static void main(String[] args) { CopyOnWriteArraySet<String> strings = new CopyOnWriteArraySet<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { strings.add(UUID.randomUUID().toString().substring(0,8)); System.out.println(strings); }, String.valueOf(i)).start(); } }
private final CopyOnWriteArrayList<E> al; // 可以看到数据结构其实是一个 CopyOnWriteArrayList 类的对象 // 让我联想到了 HashSet 和 HashMap 的关系。 public CopyOnWriteArraySet() { // 调用的是 CopyOnWriteArrayList 的构造函数 al = new CopyOnWriteArrayList<E>(); }
package JUC; import java.util.*; /** * @author zhaolimin * @date 2021/11/14 * @apiNote HashMap线程不安全 */ public class HashMapNotSafeDemo { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); for (int i = 0; i < 50; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8)); System.out.println(map); }, String.valueOf(i)).start(); } } }
public static void main(String[] args) { Map<Object, Object> objectObjectMap = Collections.synchronizedMap(new HashMap<>()); for (int i = 0; i < 40; i++) { new Thread(() -> { objectObjectMap.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8)); System.out.println(objectObjectMap); }, String.valueOf(i)).start(); } }
public static void main(String[] args) { ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>(); for (int i = 0; i < 40; i++) { new Thread(() -> { map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,8)); System.out.println(map); }, String.valueOf(i)).start(); } }
public class Person { private Integer id; private String personName; public Person() { } public Person(String personName) { this.personName = personName; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } }
public class TestTransferValueDemo { public void changeValue1(int age) { age = 30; } public void changeValue2(Person person) { person.setPersonName("zlm"); } public void changeValue3(String str) { str = "wl"; } // main线程在栈内存启动 public static void main(String[] args) { TestTransferValueDemo testTransferValueDemo = new TestTransferValueDemo(); // 基本数据类型 int age = 20; testTransferValueDemo.changeValue1(age); System.out.println("-------- age = " + age); Person person = new Person("xxx"); testTransferValueDemo.changeValue2(person); System.out.println("-------- personName = " + person.getPersonName()); String str = "xxx"; testTransferValueDemo.changeValue3(str); System.out.println("-------- str = " + str); } }
/* -------- age = 20 -------- personName = zlm -------- str = xxx */
栈管运行,堆管存储。
栈空间是线程私有,堆的是数据共享。
age的结果:
person的结果:
str的结果:
String str = new String("hello world");
运行期创建就存储在堆中。String str = "hello world;"
编译期创建的放在常量池中。码云仓库同步笔记,可自取欢迎各位star指正:https://gitee.com/noblegasesgoo/notes
如果出错希望评论区大佬互相讨论指正,维护社区健康大家一起出一份力,不能有容忍错误知识。 —————————————————————— 爱你们的 noblegasesgoo