首页
关于
友链
Search
1
wlop 4K 壁纸 4k8k 动态 壁纸
1,470 阅读
2
Nacos持久化MySQL问题-解决方案
932 阅读
3
Docker搭建Typecho博客
752 阅读
4
滑动时间窗口算法
728 阅读
5
Nginx反向代理微服务配置
699 阅读
生活
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
安全
开发工具
百度网盘
天翼网盘
阿里网盘
登录
Search
标签搜索
java
javase
docker
java8
springboot
thread
spring
分布式
mysql
锁
linux
redis
源码
typecho
centos
git
map
RabbitMQ
lambda
stream
少年
累计撰写
189
篇文章
累计收到
24
条评论
首页
栏目
生活
解决方案
JAVA基础
JVM
多线程
开源框架
数据库
前端
分布式
框架整合
中间件
容器部署
设计模式
数据结构与算法
安全
开发工具
百度网盘
天翼网盘
阿里网盘
页面
关于
友链
搜索到
4
篇与
的结果
2022-04-24
线程安全-同步容器
线程安全-同步容器主要包括ArrayList -> Vector,Stack HashMap->HashTable(key、value不能为null)Collections.synchronizedXXX(List、Set、Map)都是使用Synchronized进行修饰的,性能不是特别好。可以使用并发容器代替。注意:同步容器也可能是线程步安全的。同步容器线程步安全,代码示例:package com.yanxizhu.demo.concurrency.synContainer; import com.yanxizhu.demo.concurrency.annotation.UnThreadSafety; import java.util.Vector; /** * @description: 同步容器,也可能出现线程不安全情况 * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 10:32 * @version: 1.0 */ @UnThreadSafety public class DemoVecotNo { private static final Vector<Integer> vector = new Vector<>(); public static void main(String[] args) { //一直循环 while(true) { //向vector容器放入值 for(int i=0; i <10; i++){ vector.add(i); } //线程1,向vector容器移除值 new Thread(()->{ for(int i=0; i <vector.size(); i++){ vector.remove(i); } }).start(); //线程2,向vector中获取值 new Thread(()->{ for(int i=0; i <vector.size(); i++){ vector.get(i); } }).start(); } } }输出结果:Exception in thread "Thread-478" Exception in thread "Thread-1724" Exception in thread "Thread-1918" Exception in thread "Thread-1769" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 10 at java.base/java.util.Vector.remove(Vector.java:875) at com.yanxizhu.demo.concurrency.synContainer.DemoVecotNo.lambda$main$0(DemoVecotNo.java:27) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 62 at java.base/java.util.Vector.remove(Vector.java:875) at com.yanxizhu.demo.concurrency.synContainer.DemoVecotNo.lambda$main$0(DemoVecotNo.java:27) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 2 at java.base/java.util.Vector.get(Vector.java:781) at com.yanxizhu.demo.concurrency.synContainer.DemoVecotNo.lambda$main$1(DemoVecotNo.java:34) at java.base/java.lang.Thread.run(Thread.java:834) java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 10 at java.base/java.util.Vector.remove(Vector.java:875) at com.yanxizhu.demo.concurrency.synContainer.DemoVecotNo.lambda$main$0(DemoVecotNo.java:27) at java.base/java.lang.Thread.run(Thread.java:834) Exception in thread "Thread-4507" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 12 at java.base/java.util.Vector.get(Vector.java:781) at com.yanxizhu.demo.concurrency.synContainer.DemoVecotNo.lambda$main$1(DemoVecotNo.java:34) at java.base/java.lang.Thread.run(Thread.java:834)说明:add、remove、get防范都是通过synchronized修饰了的,为什么还是会出现线程不安全,因为当remove和get运行时,如果i相等,remove移除i时,get再获取i就包错了。Vector线程安全代码示例package com.yanxizhu.demo.concurrency.synContainer; import com.yanxizhu.demo.concurrency.annotation.ThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.Vector; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @description: 线程安全容器:Vector * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 10:18 * @version: 1.0 */ @Slf4j @ThreadSafety public class DeomVecotr { private static Vector<Integer> vector = new Vector<>(); //用户数量 private static final int clientsTotal = 5000; //并发数量 private static final int concurrencyTotal = 200; public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); //信号量 final Semaphore semaphore = new Semaphore(concurrencyTotal); //闭锁 final CountDownLatch countDownLatch = new CountDownLatch(clientsTotal); for (int i = 0; i < clientsTotal; i++) { final int count = i; executorService.execute(()->{ try { semaphore.acquire(); update(count); semaphore.release(); } catch (InterruptedException e) { log.error("出现错误:【{}】", e.getMessage()); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); log.info("vector size:{}", vector.size()); } /** * 通过线程安全对象dateTimeFormatter处理 */ private static void update(int count){ vector.add(count); } }输出结果:每次是输出5000Hashtable线程安全,代码示例:package com.yanxizhu.demo.concurrency.synContainer; import com.yanxizhu.demo.concurrency.annotation.ThreadSafety; import com.yanxizhu.demo.concurrency.annotation.UnThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @description: 线程安全容器:Hashtable * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 9:52 * @version: 1.0 */ @Slf4j @ThreadSafety public class DemoHashTable { private static Map<Integer, Integer> map = new Hashtable<>(); //用户数量 private static final int clientsTotal = 5000; //并发数量 private static final int concurrencyTotal = 200; public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); //信号量 final Semaphore semaphore = new Semaphore(concurrencyTotal); //闭锁 final CountDownLatch countDownLatch = new CountDownLatch(clientsTotal); for (int i = 0; i < clientsTotal; i++) { final int count = i; executorService.execute(()->{ try { semaphore.acquire(); update(count); semaphore.release(); } catch (InterruptedException e) { log.error("出现错误:【{}】", e.getMessage()); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); log.info("map size:{}", map.size()); } private static void update(int count){ map.put(count, count); } }输出结果:每次都是5000.线程安全。Collections.synchronizedList线程安全,同步容器package com.yanxizhu.demo.concurrency.synContainer; import com.yanxizhu.demo.concurrency.annotation.ThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @description: 安全容器,Collections下的同步容器,线程安全 * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 10:47 * @version: 1.0 */ @Slf4j @ThreadSafety public class DemoCollections { private static List<Integer> list = Collections.synchronizedList(new ArrayList<>()); //用户数量 private static final int clientsTotal = 5000; //并发数量 private static final int concurrencyTotal = 200; public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); //信号量 final Semaphore semaphore = new Semaphore(concurrencyTotal); //闭锁 final CountDownLatch countDownLatch = new CountDownLatch(clientsTotal); for (int i = 0; i < clientsTotal; i++) { final int count = i; executorService.execute(()->{ try { semaphore.acquire(); update(count); semaphore.release(); } catch (InterruptedException e) { log.error("出现错误:【{}】", e.getMessage()); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); log.info("list size:{}", list.size()); } /** * 通过线程安全对象dateTimeFormatter处理 */ private static void update(int count){ list.add(count); } }输出结果:每次输出5000,线程安全。Collections.synchronizedSet线程安全,同步容器,代码示例package com.yanxizhu.demo.concurrency.synContainer; import com.google.common.collect.Sets; import com.yanxizhu.demo.concurrency.annotation.ThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @description: 安全容器,Collections下的同步容器,synchronizedSet,线程安全 * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 10:47 * @version: 1.0 */ @Slf4j @ThreadSafety public class DemoCollectionsSynSet { private static Set<Integer> set = Collections.synchronizedSet(Sets.newHashSet()); //用户数量 private static final int clientsTotal = 5000; //并发数量 private static final int concurrencyTotal = 200; public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); //信号量 final Semaphore semaphore = new Semaphore(concurrencyTotal); //闭锁 final CountDownLatch countDownLatch = new CountDownLatch(clientsTotal); for (int i = 0; i < clientsTotal; i++) { final int count = i; executorService.execute(()->{ try { semaphore.acquire(); update(count); semaphore.release(); } catch (InterruptedException e) { log.error("出现错误:【{}】", e.getMessage()); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); log.info("set size:{}", set.size()); } /** * 通过线程安全对象dateTimeFormatter处理 */ private static void update(int count){ set.add(count); } }输出结果:每次输出5000,线程安全Collections.synchronizedMap线程安全同步容器,代码示例:package com.yanxizhu.demo.concurrency.synContainer; import com.yanxizhu.demo.concurrency.annotation.UnThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Semaphore; /** * @description: 安全容器,Collections.synchronizedMap,线程安全 * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 9:52 * @version: 1.0 */ @Slf4j @UnThreadSafety public class DemoCollectionsSynHashMap { private static Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap()); //用户数量 private static final int clientsTotal = 5000; //并发数量 private static final int concurrencyTotal = 200; public static void main(String[] args) throws InterruptedException { ExecutorService executorService = Executors.newCachedThreadPool(); //信号量 final Semaphore semaphore = new Semaphore(concurrencyTotal); //闭锁 final CountDownLatch countDownLatch = new CountDownLatch(clientsTotal); for (int i = 0; i < clientsTotal; i++) { final int count = i; executorService.execute(()->{ try { semaphore.acquire(); update(count); semaphore.release(); } catch (InterruptedException e) { log.error("出现错误:【{}】", e.getMessage()); } countDownLatch.countDown(); }); } countDownLatch.await(); executorService.shutdown(); log.info("map size:{}", map.size()); } private static void update(int count){ map.put(count, count); } }输出结果:每次输出5000,线程安全。常用操作错误package com.yanxizhu.demo.concurrency.synContainer; import java.util.Iterator; import java.util.Vector; /** * @description: 常见容器使用错误,解决办法 * @author: <a href="mailto:vip@foxmail.com">清风</a> * @date: 2022/4/24 11:04 * @version: 1.0 */ public class DemoErrorUser { //增强for循环中修改,报错:java.util.ConcurrentModificationException public static void test1(Vector<Integer> vector) { for (Integer integer: vector) { //使用增强for循环 if (integer.equals(3)) { // vector.remove(integer); vector.add(4); } } } //迭代器中循环修改,报错:java.util.ConcurrentModificationException public static void test2(Vector<Integer> vector) { Iterator<Integer> iterator = vector.iterator(); while (iterator.hasNext()){ Integer integer = iterator.next(); if( integer.equals(3)) { vector.remove(integer); } } } //普通for循环中修改,正常。 public static void test3(Vector<Integer> vector) { for(int i=0; i< vector.size(); i++) { if(i==3) { vector.remove(i); } } } //总结:增强for、迭代器循环中修改,可以先标记,然后最后进行修改。 public static void main(String[] args) { Vector<Integer> vector = new Vector<>(); vector.add(1); vector.add(2); vector.add(3); test1(vector); // test2(vector); // test3(vector); } }输出结果:ConcurrentModificationExceptionException in thread "main" java.util.ConcurrentModificationException at java.base/java.util.Vector$Itr.checkForComodification(Vector.java:1321) at java.base/java.util.Vector$Itr.next(Vector.java:1277) at com.yanxizhu.demo.concurrency.synContainer.DemoErrorUser.test1(DemoErrorUser.java:16) at com.yanxizhu.demo.concurrency.synContainer.DemoErrorUser.main(DemoErrorUser.java:52)增强for、迭代器中循环修改线程报错,正常for循环,正常,解决办法,通过标记后,再单独进行移除操作。
2022年04月24日
213 阅读
0 评论
2 点赞
2022-04-22
不可变对象
线程安全策略不可变对象不可变对象需要满足的条件:对象创建以后其状态就不能修改对象所有域都是final类型对象是正确创建的(在对象创建期间,this引用没有逸出)一、final关键字final关键字:可修饰类、方法、变量。修饰类:不能被继承修饰方法:锁定方法不被继承类修改;效率修饰变量:基本数据类型变量、引用类型变量代码示例package com.yanxizhu.demo.concurrency.finals; import com.google.common.collect.Maps; import com.yanxizhu.demo.concurrency.annotation.UnThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.Map; /** * @description: 不可变对象 final修饰 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 20:35 * @version: 1.0 */ @Slf4j @UnThreadSafety public class DemoFinal { //普通类型,final修饰后,修改直接提示错误 private final static Integer a =1; //普通类型,final修饰后,修改直接提示错误 private final static String b = "hello"; //final修饰后不能在执行新的对象 private final static Map<Integer, Integer> map = Maps.newHashMap(); static { map.put(1, 2); map.put(2, 3); map.put(4, 5); } public static void main(String[] args) { //指向新的对象,直接报错 // map = new Maps.newHashMap(); //值可以修改,但是线程不安全 map.put(1, 6); log.info("{}", map.get(1)); // 输出结果:- 6 } //fina修饰形参,传入后也不能修改 public void test(final int a) { //报错 // a =2; } }输出结果: - 6二、Collections.unmodifiableXXXXX代码示例package com.yanxizhu.demo.concurrency.finals; import com.google.common.collect.Maps; import com.yanxizhu.demo.concurrency.annotation.UnThreadSafety; import lombok.extern.slf4j.Slf4j; import java.util.Collections; import java.util.Map; /** * @description: Collections.unmodifiableXXXXX,值是不能修改的,但是是线程安全的 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 21:12 * @version: 1.0 */ @Slf4j @UnThreadSafety public class DemoCollections { private static Map<Integer, Integer> map = Maps.newHashMap(); static { map.put(1, 2); map.put(3, 4); map.put(5, 6); map = Collections.unmodifiableMap(map); } public static void main(String[] args) { map.put(1, 8); log.info("{}", map.get(1)); } }输出结果:Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.Collections$UnmodifiableMap.put(Collections.java:1457) at com.yanxizhu.demo.concurrency.finals.DemoCollections.main(DemoCollections.java:28)Collections.unmodifiableXXXXX创建的不能修改,修改提示"UnsupportedOperationException"。但是是线程安全的。常见方法有三、google的Guava工具类,ImmutableXXX代码示例package com.yanxizhu.demo.concurrency.finals; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.yanxizhu.demo.concurrency.annotation.ThreadSafety; /** * @description: google Guava工具类实现对象不可变,线程安全,但是不能修改值 * @author: <a href="mailto:batis@foxmail.com">清风</a> * @date: 2022/4/22 21:39 * @version: 1.0 */ @ThreadSafety public class DemoGuavaImmutableXXX { //ImmutableList会提示不能修改,建议用这个 private final static ImmutableList list = ImmutableList.of(2,3,5); //list不会提示不能修改 // private final static List<Integer> list = ImmutableList.of(2,3,5); //set同理不能修改值 private final static ImmutableSet set = ImmutableSet.copyOf(list); //map方式一,map用法有点区别,是key,value的形式 //(key1,value1,key2,value2,.......) private final static ImmutableMap<Integer, Integer> map = ImmutableMap.of(1,2,3,4,5,6); //map方法二,初始值有点不同 private final static ImmutableMap<Integer, Integer> map2 = ImmutableMap.<Integer, Integer>builder(). put(1, 2).put(3, 4).put(5, 6).build(); public static void main(String[] args) { //提示错误:UnsupportedOperationException // list.add(4); //set同样会提示不能修改,提示".UnsupportedOperationException" // set.add(4); //map同理,不能修改值,否则也提示 UnsupportedOperationException map.put(3, 2); } }输出结果:Exception in thread "main" java.lang.UnsupportedOperationException at com.google.common.collect.ImmutableMap.put(ImmutableMap.java:780) at com.yanxizhu.demo.concurrency.finals.DemoGuavaImmutableXXX.main(DemoGuavaImmutableXXX.java:40)注意:是不能修改,读取是没问题的。使用不可变对象时,注意实际业务看法种,对象是否不可以变,不可变才使用上面3种方法,实现不可变对象。
2022年04月22日
159 阅读
0 评论
3 点赞
2022-03-19
CopyOnWriteArrayList遍历集合
package com.yanxizhu; import java.util.*; /** * @description: synchronizedList遍历错误 * @date: 2022/3/19 11:30 * @version: 1.0 */ public class ConCurrentHashMapTest { public static void main(String[] args) { conCurrentDemo conCurrentDemo = new conCurrentDemo(); for(int i=0;i<5;i++){ new Thread(conCurrentDemo).start(); } } public static class conCurrentDemo implements Runnable{ //并发线程安全,修改报错 private static List<String> list = Collections.synchronizedList(new ArrayList<>()); static { list.add("apple"); list.add("xiaomi"); list.add("huawei"); } @Override public void run() { Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); list.add("iphone"); } } } }线程安全报错:Exception in thread "Thread-0" Exception in thread "Thread-3" Exception in thread "Thread-4" Exception in thread "Thread-2" Exception in thread "Thread-1" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997) at com.yanxizhu.ConCurrentHashMapTest$conCurrentDemo.run(ConCurrentHashMapTest.java:35) at java.base/java.lang.Thread.run(Thread.java:834) java.util.ConcurrentModificationException at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1043) at java.base/java.util.ArrayList$Itr.next(ArrayList.java:997) at com.yanxizhu.ConCurrentHashMapTest$conCurrentDemo.run(ConCurrentHashMapTest.java:35) at java.base/java.lang.Thread.run(Thread.java:834)通过用CopyOnWriteArrayList修改:package com.yanxizhu; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; /** * @description: CopyOnWriteArrayList遍历集合 * @date: 2022/3/19 11:30 * @version: 1.0 */ public class ConCurrentHashMapTest { public static void main(String[] args) { conCurrentDemo conCurrentDemo = new conCurrentDemo(); for(int i=0;i<5;i++){ new Thread(conCurrentDemo).start(); } } public static class conCurrentDemo implements Runnable{ //并发线程安全,修改报错 // private static List<String> list = Collections.synchronizedList(new ArrayList<>()); private static CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>(); static { list.add("apple"); list.add("xiaomi"); list.add("huawei"); } @Override public void run() { Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); //CopyOnWriteArrayList,每次会重新复制一个新的,添加。 list.add("iphone"); } } } }
2022年03月19日
214 阅读
0 评论
2 点赞
2022-03-08
高并发中集合问题
第一代线程安全集合类Vector、Hashtable是怎么保证线程安排的:使用synchronized修饰方法缺点:效率低下第二代线程非安全集合类ArrayList、HashMap线程不安全,但是性能好,用来替代Vector、Hashtable使用ArrayList、HashMap,需要线程安全怎么办呢?使用Collections.synchronizedList(list);Collections.synchronizedMap(m);底层使用synchronized代码块锁虽然也是锁住了所有的代码,但是锁在方法里边,并所在方法外边性能可以理解为稍有提高吧。毕竟进方法本身就要分配资源的第三代线程安全集合类在大量并发情况下如何提高集合的效率和安全呢?java.util.concurrent.*ConcurrentHashMap:CopyOnWriteArrayList:CopyOnWriteArraySet:注意不是CopyOnWriteHashSet*底层大都采用Lock锁(1.8的ConcurrentHashMap不使用Lock锁),保证安全的同时,性能也很高。
2022年03月08日
150 阅读
0 评论
2 点赞