JAVA线程使用实例 java多线程如何实现在多CPU上分布?

[更新]
·
·
分类:互联网
2271 阅读

JAVA线程使用实例

java多线程如何实现在多CPU上分布?

java多线程如何实现在多CPU上分布?

在java里创建几个线程怎么能确保他们跑在不同的CPU上?可以控制它们的分布吗?

一个JAVA线程就是一个OS线程,线程调度依赖于操作系统,JVM层面不干预。
JAVA语言层面讲,只是规范,并不要求具体如何实现。具体的实现模型有几种,比如1:1,N:1, 1:N,具体怎么选,JVM厂商自己的事儿。
在LINUX下,你可以用JNI来调用taskset,实现把线程分配到某一个CPU上。但是这么做的理由我现在还想不出来。

java中,10个线程并发修改1个大数组(亿级别),用1个mutex怎么设计最高效安全?

不管什么语言,用多线程和1个mutex处理这样的数据是最蠢的想法。
应该避免这样的大数据出现,不要积压未处理数据,尽可能在数据量小时处理掉如果避免不了大数据,就采用分层过滤的方式,用一个线程把数据整理分块为10个,然后把这10块分配给10个线程处理各自处理,甚至可以按1、2、4、8个块分别对应1、2、4、8个线程处理。分块只是在数组的下标进行划分。这样才是真正意义的使用多线程的优势,无锁操作

设想这样一个全局扩展锁对象,它控制一个地址集,可以进行append和delete操作,它在append操作的时候会检测自己的数据集是否有重复数据,只要重复就lock。delete操作不做限制。这十个线程,每次需要访问大数组式,把索引append进扩展锁,用后就delete这个索引。
进一步,扩展这个锁对象,增加一个锁定访问方法,数组索引和一个lamda函数作为参数,专门干append索引,执行lamda,delete索引这种勾当。主要是防止自己忘了delete。
再进一步,提供调试功能,在锁定访问方法内部,在append前向系统报告时间标签,执行时报告一次,解锁报告一次。这样,你就可以获取性能报告了。
我想不出还能不能进一步了,就这样吧。

每个线程处理各自的下标范围就可以了,不需要互斥锁,当然了,不能是byte数组

Java并发线程如何阻塞和唤醒?

每个对象都有两个方法wait和notify,加上同步

Java并发线程的阻塞和唤醒可分几类:
1. synchronize基于JVM的对象头来实现,多线程争抢同一个临界资源时根据不同的锁机制(自旋锁、轻/重量级锁)来进行阻塞和唤醒。
2. notify/wait,yeild等基础机制这里暂时略过,大致实现原理是基于对象的同步队列和后面的AQS很像。
3. 并发组件的基础AQS重点说下AQS(AbstractQueuedSynchronizer),
因为这是jdk并发包实现的基础(如Lock、BlockingQueue、CountdownLatch等)。
Aqs基本由一个volatile变量state和一个等待队列来实现,抢锁时先CAS修改state,失败以后就放到等待队列里,并通过LockSupport将线程挂起。
当锁的拥有者释放锁时会通过LockSupport唤醒等待队列的后续节点,让它再次去尝试抢锁(CAS修改state),如此反复。
掌握AQS的原理对理解jdk里很多并发组件非常有帮助。

1. sleep() 方法:以毫秒为单位,使线程处于阻塞状态,时间到了过后,自动唤醒。
() 和 resume() 方法:挂起和唤醒线程,suspend e()使线程进入阻塞状态,只有对应的resume e()被调用的时候,线程才会进入可执行状态。这个不建议使用,容易发生死锁情况。
3. yield() 方法:调用 yield()的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程
这里就说这三种吧,其它的你可以去csdn上门看看,学习一下