java并发编程之并发编程的挑战

上下文切换:

CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。--------摘自《java并发编程的艺术》

1、多线程一定快吗?

多线程并发执行的速度不一定会比串行快,因为线程有创建和上线文切换的开销。

2、测试上下文切换次数和时长?(略)

3、如何减少上下文切换?

减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程、使用协程。
  • 无锁并发编程
    多线程竞争锁时,会引起上下文切换,所以可以用一些办法来避免使用锁,如Hash算法取模分段,不通的线程处理不通段的数据。
    应用场景:JDK1.6中ConcurrentHashMap的Segment分段锁就采用了这种发方法。
  • CAS算法
    比较与交换算法,一种乐观锁
    应用场景:Java的Atomic包使用CAS算法来更新数据,而不需要加锁。
  • 使用最少线程
    避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。
  • 协程
    在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。
    应用场景:NIO及基于NIO的Netty

4、减少上下文切换实战?(略)

死锁:

1、 死锁演示(t1和t2线程互相等待对方释放锁)

public class DeadLockDemo {
    public static void main(String[] args) {
        String A = "A";
        String B = "B";
        Thread t1 = new Thread(() -> {
            synchronized (A) {                            // t1获取对象A的锁
                try {
                    Thread.sleep(1000);             // t1阻塞1S,模拟处理业务逻辑
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (B) {                        // t1等待对象B的锁
                    System.out.println(Thread.currentThread().getName() + "B");
                }
            }
        });
        Thread t2 = new Thread(() -> {
            synchronized (B) {                            // t2获取对象B的锁
                try {
                    Thread.sleep(1000);            // t2阻塞1S,模拟处理业务逻辑
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (A) {                        // t2等待对象A的锁
                    System.out.println(Thread.currentThread().getName() + "A");
                }
            }
        });
        t1.start();
        t2.start();
    }
}

2、 避免死锁的几个常见方法

  • 避免一个线程同时获取多个锁
  • 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
  • 尝试使用定时锁来替代使用内部锁机制
lock.tryLock(1000, TimeUnit.MILLISECONDS)
  • 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况???(这个方法不是很理解)

资源限制(略)

小结:

在进行并发编程时,多使用JUC下的并发容器和工具类来解决并发问题,因为这些类都已经通过了充分的测试和优化,均可解决以上的几个挑战。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值