《java并发编程的艺术》第一章总结

并发编程的目的是为了让程序更快地运行,但是,启动更多的线程并不一点让程序最大程度的并行。

上下文切换

单核处理器也能多线程执行代码,处理器是通过时间片的快速切换来实现多线程的,时间片的时间非常短,所以CPU要不停的切换线程执行,时间片一般是十几毫秒。

所以当前任务执行完一个时间片后会切换到下一个任务。但是,在切换前会保存上一个线程的状态,下次切换回该线程时可以再加载这个任务的状态。任务从保存到加载就是一次上下文切换。

根据上下文切换的定义,CPU在切换线程时会保存状态和加载状态,这样的切换同样也是消耗时间的,频繁的上下文切换会影响程序的执行速度,以书中的程序为例:
 

public class ConcurrencyTest {

private static final long count = 10000l;

public static void main(String[] args) throws InterruptedException { concurrency(); serial(); } private static void concurrency() throws InterruptedException {

long start = System.currentTimeMillis();

Thread thread = new Thread(new Runnable() {

@Override public void run() {

int a = 0; for (long i = 0; i < count; i++) { a += 5; }

        }

});

thread.start();

int b = 0;

for (long i = 0; i < count; i++) { b--; }

long time = System.currentTimeMillis() - start; thread.join();

System.out.println("concurrency :" + time+"ms,b="+b);

}

private static void serial() {

long start = System.currentTimeMillis();

int a = 0;

for (long i = 0; i < count; i++) { a += 5; }

int b = 0;

for (long i = 0; i < count; i++) { b--; }

long time = System.currentTimeMillis() - start;

System.out.println("serial:" + time+"ms,b="+b+",a="+a);

}

 当执行操作不超过百万次时,并行执行累加操作会比串行要慢。

通过vmstat测试上下文切换次数

程序每一秒切换1000多次

减少上下文切换可以通过减少线上的WAITING线程

死锁

简单的说有以下几种情况会造成死锁

1、忘记解锁

2、同一个线程中对同一个资源多次加锁

3、有两个线程,两个线程都不释放拥有的锁,也都获取不到等待的锁。

这样就会造成死锁,书上死锁的程序比较简单,这里就不多加描述了。

死锁对于程序来说一定是不可容忍的,我们一定要尽量避免死锁,以下几个方法可以一定程度上避免死锁

1、避免一个线程同时获得多个锁

2、避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源

3、尝试使用定时锁

4、数据库锁的加锁和解锁必须在一个数据库连接里

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值