下面这样写法是Vector线程不安全的写法:
import java.util.Vector; public class Test { private static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) { while (true) { for (int i = 0; i < 10; i++) { System.out.println("添加"); vector.add(i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < vector.size(); i++) { System.out.println("removeThread删除"); vector.remove(i); } } }); Thread printThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < vector.size(); i++) { System.out.println("printThread获取"); System.out.println((vector.get(i))); } } }); removeThread.start(); printThread.start(); //不要同时产生过多的线程,否则会导致操作系统假死 while (Thread.activeCount() > 20); } }
} }
尽管Vector get()、remove()、get() 方法是I同步的 但运行上面程序会出现以下错误:
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 at java.util.Vector.get(Vector.java:744) at Test$2.run(Test.java:29) at java.lang.Thread.run(Thread.java:722) Exception in thread "Thread-14857" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0 at java.util.Vector.get(Vector.java:744) at Test$2.run(Test.java:29)
HashTable线程不安全写法:
import java.util.Hashtable; import java.util.Map; public class HashmapTest { private static Map<Integer,Integer> hashtable= new Hashtable<Integer,Integer>(); public static void main(String[] args) { while(true){ for (int i = 0; i < 10; i++) { System.out.println("添加"); hashtable.put(i, i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { Iterator it = hashtable.entrySet().iterator(); while (it.hasNext()) { Map.Entry<integer integer=""> entry=(Entry<integer integer="">) it.next(); System.out.println("delete this: "+entry.getKey()+"==="+entry.getValue()); it.remove(); } } Thread getThread = new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < hashtable.size(); i++) { System.out.println("getThread获取"); System.out.println((hashtable.get(i))); } } }); removeThread.start(); getThread.start(); while (Thread.activeCount() > 20); } } }
会出现很多null值,但不错,因为没有那个key ,但不会报错
getThread获取 null getThread获取 null
在多线程环境中,如果不在方法调用端做额外的同步措施,使用这段仍是线程不安全的,因为如果一个线程恰好再错误的时间删除了一个元素, 导致i不在可用的话,get方法会抛出一个ArrayIndexOutOfBoundsException
import java.util.Vector; public class Test { private static Vector<Integer> vector = new Vector<Integer>(); public static void main(String[] args) { while (true) { for (int i = 0; i < 10; i++) { System.out.println("添加"); vector.add(i); } Thread removeThread = new Thread(new Runnable() { @Override public void run() { synchronized (vector) { for (int i = 0; i < vector.size(); i++) { System.out.println("removeThread删除"); vector.remove(i); } } } }); Thread printThread = new Thread(new Runnable() { @Override public void run() { synchronized (vector) { for (int i = 0; i < vector.size(); i++) { System.out.println("printThread获取"); System.out.println((vector.get(i))); } } } }); removeThread.start(); printThread.start(); //不要同时产生过多的线程,否则会导致操作系统假死 while (Thread.activeCount() > 20); } } }
Stay hungry,stay foolish !
分类:
数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构