Java并发编程 01 并发注意事项

来源:互联网 发布:mac打开文件夹命令 编辑:程序博客网 时间:2024/06/05 03:40

做并发编程的时候需要注意哪些事项呢?

上下文开销

CPU的线程是通过调度算法分配不同的时间片,当一条线程的时间片用完后,操作系统会暂停该线程,并保存该线程相应的信息,然后再随机选择一条新线程去执行,这个过程就称为“线程的上下文切换”。

每次进行上下文切换时都需要保存当前线程的执行状态,并加载新线程先前的状态。 如果上下文切换频繁,CPU花在上下文切换上的时间占比就会上升,而真正处理任务的时间占比就会下降。

如何减少上下文切换?

减少线程的数量 。然而如果线程数量已经少于CPU核数,每个CPU执行一条线程,照理来说CPU不需要进行上下文切换了,但事实并非如此。

控制同一把锁上的线程数量。如果多条线程共用同一把锁,那么当一条线程获得锁后,其他线程就会被阻塞;当该线程释放锁后,操作系统会从被阻塞的线程中选一条执行,从而又会出现上下文切换。
因此,减少同一把锁上的线程数量也能减少上下文切换的次数。

采用无锁并发编程。 如果减少同一把锁上线程的数量就能减少上下文切换的次数,那么如果不用锁,是否就能避免因竞争锁而产生的上下文切换呢? 需要根据以下两种情况挑选不同的策略:

需要并发执行的任务是无状态的:HASH分段 需要并发执行的任务是有状态的:CAS算法 

死锁问题

当多个线程相互等待已经被对方占用的资源时,就会产生死锁。

如何避免死锁?

不要在一条线程中嵌套使用多个锁;不要在一条线程中嵌套占用多个计算机资源;给锁和资源加超时时间 如果你非要在一条线程中嵌套使用多个锁或占用多个资源,那你需要给锁、资源加超时时间,从而避免无限期的等待。

通信机制

线程之间的通信一共有两种方式:共享内存 和 消息传递。

共享内存:这种方式有个弊端,即需要程序员来控制线程的同步,即线程的执行次序。

消息传递 :由于执行次序由并发机制完成,因此不需要程序员添加额外的同步机制,但需要声明消息发送和接收的代码。

综上所述:对于共享内存的通信方式,需要进行显示的同步,隐式的通信; 而对于消息传递的通信方式,需要隐式的同步,显示的通信。

Java使用共享内存的方式实现多线程之间的消息传递。因此,程序员需要写额外的代码用于线程之间的同步。

Java采用共享内存的方式实现消息传递,而共享内存需要依托于同步。Java提供了synchronized、volatile关键字实现同步。此外volatile关键字还拥有一些额外的功能。

原创粉丝点击