【Java并发编程六】多线程越界问题

ArrayList()越界错误

java 复制代码
import java.util.ArrayList;
public class myTest implements Runnable {
    static ArrayList<Integer> a = new ArrayList<>(10);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new myTest());
        Thread t2 = new Thread(new myTest());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(a.size());
    }
    @Override
    public void run() {
        for(int i=0; i<10000; i++) {
            a.add(i);
        }
    }
}

上面的代码会有三种可能的运行结果:

①越界。因为List的add方法会先检查list是否足够,从而选择扩容,若第一个线程刚刚扩容完毕,还未添加,第二个线程就进行了检查,从而导致list越界。

②正常结果。结果为20000。

③异常结果。这是因为两个线程同时对i的值进行修改。

HashMap

HashMap也会出现上述情况。

解决措施

使用synchronized修饰方法。

java 复制代码
import java.util.ArrayList;
public class myTest implements Runnable {
    static ArrayList<Integer> a = new ArrayList<>(10);
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new myTest());
        Thread t2 = new Thread(new myTest());
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(a.size());
    }
    public static synchronized void func() {
        for(int i=0; i<10000; i++) {
            a.add(i);
        }
    }
    @Override
    public void run() {
        func();
    }
}
相关推荐
茶本无香6 小时前
设计模式之五—门面模式:简化复杂系统的统一接口
java·设计模式
阿华hhh6 小时前
day4(IMX6ULL)<定时器>
c语言·开发语言·单片机·嵌入式硬件
她说可以呀6 小时前
网络基础初识
java·网络·java-ee
没有bug.的程序员6 小时前
Java锁优化:从synchronized到CAS的演进与实战选择
java·开发语言·多线程·并发·cas·synchronized·
初九之潜龙勿用6 小时前
C#实现导出Word图表通用方法之散点图
开发语言·c#·word·.net·office·图表
历程里程碑6 小时前
Linux 2 指令(2)进阶:内置与外置命令解析
linux·运维·服务器·c语言·开发语言·数据结构·ubuntu
麦兜*6 小时前
SpringBoot Profile多环境配置详解,一套配置应对所有场景
java·数据库·spring boot
MetaverseMan6 小时前
rpc节点: synchronized (this) + 双检锁,在 race condition 的情况下分析
java·区块链
笃行客从不躺平6 小时前
Seata + AT 模式 复习记录
java·分布式
王燕龙(大卫)6 小时前
rust入门
开发语言·rust