决战圣地玛丽乔亚Day32---JUC并发包的核心内容

copyOnWrite容器用途

写时复制机制,在修改操作时,复制一个副本,修改副本,再修改完后再替换回去。避免了高并发期间的竞争。 

使用场景:

对于一些读多写少的数据,写时复制的做法就很不错,例如配置、黑名单、物流地址等变化非常少的数据,这是一种无锁的实现,可以帮我们实现程序更高的并发

CopyOnWriteArrayList并发安全且性能比Vector好。Vector是curd方法都加了synchronized来保证同步,但是每个方法执行的时候都要去获得锁,性能就会大大下降,而COW只是在增删改上加锁,读不加锁,在读方面的性能就好于Vector。

 

注意两个问题 

1.内存问题。

多个变量指向同一内存地址,如果某一变量修改数据,会形成副本,副本会占用空间。

如果CopyOnWriteArrayList经常要增删改里面的数据,并且对象比较大,频繁地写会消耗内存,从而引发Java的GC问题,这个时候,我们应该考虑其他容器,例如ConcurrentHashMap

当数据修改完成后,原内存地址会变得无用,导致内存碎片的产生。

2.数据一致性问题。

只能保证最终一致性,不能保证实时一致性。

 

 

Unsafe类的用途

 

在Java编程语言中,Unsafe类提供了一种非常底层的操作方式,可以用于执行一些危险或不安全的操作,包括:

  1. 直接操作内存:Unsafe类提供了一些方法来读取、写入和操作内存,例如putIntgetIntallocateMemory等。这些方法可以用于优化某些性能关键的算法,但同时也可能导致内存访问错误,甚至是崩溃。

  2. 修改对象字段:Unsafe类可以绕过Java对象的访问限制,直接修改对象的字段。这在一些极端情况下可能是必要的,但也会破坏对象的封装性,导致对象状态不可预测。

  3. 创建实例:Unsafe类提供了一些方法来创建类的实例,包括绕过构造函数直接分配内存和初始化字段。这可以用于实现一些高级技术,例如对象池和反序列化,但也可能导致对象状态不一致和内存泄漏。

需要注意的是,由于Unsafe类的操作非常底层,因此在使用时需要格外小心,避免出现潜在的安全隐患和错误。建议只有在真正需要时才使用Unsafe类,否则应该优先选择更安全、更易于维护的解决方案。

 

 

Callable和Runnable的区别?

 示例:

1
2
3
4
5
6
7
8
/ Runnable 示例
Runnable runnable = new Runnable() {
    public void run() {
        // 执行一些操作
    }
};
Thread thread = new Thread(runnable);
thread.start();<br>
1
2
3
4
5
6
7
8
9
10
// Callable 示例
Callable<String> callable = new Callable<String>() {
    public String call() throws Exception {
        // 执行一些操作
        return "result";
    }
};
ExecutorService executorService = Executors.newSingleThreadExecutor();
Future<String> future = executorService.submit(callable);
String result = future.get(); // 等待操作完成并获取结果

  

返回值:Runnable的run方法没有返回值,callable可以返回一个结果。

异常处理:run不能抛出异常 ,call可以抛出异常

使用方式:是否需要返回值来决定场景。

如果需要用run来执行一个可能会异常的操作,在run里面需要手动写一下异常处理。

 

CompleteFuture的使用?

 

posted @   NobodyHero  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
· 零经验选手,Compose 一天开发一款小游戏!
点击右上角即可分享
微信分享提示