5 多线程,原子操作

时间:2021-12-31 18:31:53

推荐高洪岩的《Java多线程编程核心技术》,虽然很多代码都是纯粹为了炫耀技术,但看完之后再也不怕被多线程问倒了

随笔提一句,前面看了那多章同步代码块的内容,后面却发现lock完全可以取代。这本书在我看来可以砍掉一半,直接用Lock就好了。

 

问题1:用Java写代码来解决生产者——消费者问题

使用lock实现,另外MQ消息队列的点对点模式也是同样的原理,以及duboo的发布订阅模式。

  MY:关键是搞明白何时阻塞、唤醒相关线程;wait/nofityAll
 1  
 2 hasv=false;
 3  
 4  
 5 set()
 6 {
 7  lock.lock()
 8 while(hasv==true)
 9 {
10   condition.await();
11 }
12 hasv=true;
13 condition.signal();
14 }
15 finally lock.unlock();
16 }
17  
18 get()
19 {
20   和set类似相反
21 }

 

 
 
run.java:
10个AB线程一起启动,A使用set,B使用get。就会交替执行A和B。使hasv的值改变,可打印信息查看
i=0,i<10,i++
threadA[i].start()
threadB[i].start()

 

 问题2:原子操作

double、long是 64位的,32位系统会赋值两次(即两个原子操作),在多线程环境下,可能刚读高32位,低32位被其他写覆盖了。

因此使用volatile关键字,确保在并发环境中确保可见性、顺序性和一致性。一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。

精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

volatile是程度较轻的  synchronized,这个关键字非常不好控制,干脆不用为好。
使用场景:可以用在Long个double变量上,见上面原子操作

问题3:多线程实战

A 在顶置的偏光片切割利用到,主要矛盾是CPU运算耗时长,打开任务管理发现双核CPU总是占用50%,另一核心根本没使用。

于是改成多线程计算,计算次数是可预见的,直接粗暴的按照CPU核心数来创建线程数量。然后等待所有线程运算完毕,结果集合并。

 

B 手动实现消费者-生产者模式

 

5 多线程,原子操作