java多线程 读取list--动态读取list
java多线程 读取list--动态读取list的案例
本次介绍,我使用的是synchronized 同步代码块的关键字来读取list,在写java多线程时,一定要注意
synchronized 关键字的有效范围。
ps:
如果synchronized 关键字的代码块范围太大,可能会导致 优先获取到cpu资源的第一个线程 在满足条件的情况下 一直无法跳循环,从而使得其他线程
无法给获取到被cpu调度的机会,造成:想“多线程执行代码块”的预期-》演变成了 “单线程一路走到黑 执行代码块”的惨象,也就是让多线程的预期 实际变成了单线程了。
以下 我就用1个错误的例子,和一个正确的例子给大家介绍以下吧:
1.错误的例子:实际是单线程 执行synchronized代码块的内容:
package com.cdncp.testautomation.control.conf; import java.util.ArrayList; import java.util.List; public class Test_4 { /** * 多线程处理list * * @param data 数据list * @param threadNum 线程数 */ public void handleList(List<String> data, int threadNum) { long start = System.currentTimeMillis(); for (int i = 0; i < threadNum; i++) { HandleThread thread = new HandleThread("线程[" + (i + 1) + "] ", data); thread.start(); System.out.println("thread name:" + thread.getName()); } long end = System.currentTimeMillis(); System.out.println("time:" + (end - start)); } public static void main(String[] args) { Test_4 test = new Test_4(); // 准备数据 List<String> data = new ArrayList<String>(); for (int i = 0; i < 40; i++) { data.add("item" + i); } HandleThread.info = data; test.handleList(data, 10); } }
第二个类:
package com.cdncp.testautomation.control.conf; import java.util.List; public class HandleThread extends Thread { public static List<String> info; private String threadName; private List<String> data; //静态钥匙 static Object ob = "key"; //值是任意的 public HandleThread(String threadName, List<String> data) { this.threadName = threadName; this.data = data; } @Override public void run() { while (true) { synchronized (HandleThread.class) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if (info.size() > 0) { System.out.println(this.threadName + ": " + info.toString()); info.remove(info.get(0)); } else { System.out.printf("%s:票已售空 \n", getName()); break; } } } } }
执行结果:
无法满足 按照我设定的线程数 去动态读取list(虽然读取数据是线程安全的,但是线程数不能按照预期创建的个数执行)
2.正确的例子:实现按照预定创建的 多线程 执行synchronized代码块的内容:
package com.cdncp.testautomation.control.conf; import java.util.ArrayList; import java.util.List; public class Test_4 { /** * 多线程处理list * * @param data 数据list * @param threadNum 线程数 */ public void handleList(List<String> data, int threadNum) { long start = System.currentTimeMillis(); for (int i = 0; i < threadNum; i++) { HandleThread thread = new HandleThread("线程[" + (i + 1) + "] ", data); thread.start(); System.out.println("thread name:" + thread.getName()); } long end = System.currentTimeMillis(); System.out.println("time:" + (end - start)); } public static void main(String[] args) { Test_4 test = new Test_4(); // 准备数据 List<String> data = new ArrayList<String>(); for (int i = 0; i < 40; i++) { data.add("item" + i); } HandleThread.info = data; test.handleList(data, 10); } }
第二个类:
区别就是synchronized设置的代码块范围:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | package com.cdncp.testautomation.control.conf; import java.util.List; public class HandleThread extends Thread{ public static List<String> info; private String threadName; private List<String> data; //静态钥匙 static Object ob = "key" ; //值是任意的 public HandleThread(String threadName, List<String> data) { this .threadName = threadName; this .data = data; } @Override public void run() { while ( true ) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } if (info.size() > 0) { synchronized (HandleThread. class ) { if (info.size() > 0) { System. out .println( this .threadName + ": " + info.toString()); info.remove(info. get (0)); } } //可以写其他不需要加锁的,希望让多线程并发执行的代码块 } else { System. out .printf( "%s:票已售空 \n" , getName()); break ; } } } } |
ps:
我创建了9个线程,这里也是个线程去执行代码块,获取list中的数据!!!
原因分析:
如果synchronized 关键字的代码块范围太大(其实本质还是 同步代码块没写对),可能会导致 优先获取到cpu资源的第一个线程 在满足条件的情况下 一直无法跳循环,那么这个线程就一直占用cpu资源,一直执行。
synchronized 关键字的代码块的特别是:同一时间就只能有一个线程去执行,只有等这个线程执行完毕这个代码块后,资源才会被释放,然后才能让其他线程去执行这个synchronized 关键字的代码块。
案例一中,就是因为这个原因,这就从而使得其他线程(即使我创建了9个线程,其实就只要小于9个线程在执行) 无法获取到被cpu调度的机会,其他线程也就不能执行了!!!
分类:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)