读书笔记《Java并发编程的艺术 - 方腾飞》- 并发的两个‘老‘问题

2020-11-25 15:12:07 浏览数 (2)

并发的两个‘老’问题

上一篇文章我们认识了什么是并发编程,随着并发编程而来的则是并发带来的各种问题,死锁和资源问题,那这一篇我们继续跟着作者去看一看这两个‘老‘问题。

死锁

我理解的死锁是指 “无外界条件干预无法自行解决的一种状态”

这种状态一旦出现会导致程序逻辑问题,资源占用问题等很严重的问题。

下面这段代码截自书中的代码, 演示了死锁的场景

代码语言:javascript复制
public class DeadLockDemo {
    privat static String A = "A";
    private static String B = "B";
    public static void main(String[] args) {
              new DeadLockDemo().deadLock();
    }
    private void deadLock() {
              Thread t1 = new Thread(new Runnable() {
                        @Override
                        publicvoid run() {
                                  synchronized (A) {
                                          try { Thread.currentThread().sleep(2000);
                                          } catch (InterruptedException e) {
                                                    e.printStackTrace();
                                          }
                                          synchronized (B) {
                                                    System.out.println("1");
                                          }
                                  }
                        }
              });
              Thread t2 = new Thread(new Runnable() {
                        @Override
                        publicvoid run() {
                                  synchronized (B) {
                                          synchronized (A) {
                                            System.out.println("2");
                                    }
                          }
                }
      });
      t1.start();
      t2.start();
}
}

当出现死锁的时候, 线上的业务是可以反馈出来的, 同时我们通过线程 dump 是可以查询到具体的死锁地方.

当我们知道什么是死锁问题后, 那就应该在开发阶段首先去考虑并且避免这种场景

  • 避免一个线程获取多个锁
  • 避免一个线程在锁内占用多个资源
  • 如果可以的话尝试使用 tryLock(time) 定时锁
  • 数据库锁, 加锁和解锁在一个连接, 否则可能出现解锁失败

资源

什么是资源,对于软件程序来说资源就是

  • 网络带宽
  • 内存容量
  • cpu
  • ······

:那什么情况会出现资源问题呢?

:不合理的分配情况下

怎么做才能做到合理分配是我们在做程序设计时需要考虑的,比如软件运行的网络环境,磁盘大小,内存大小,系统的cpu能力、核心数等等

一般在资源分配上遵循两种任务情况来决定,1 是 IO密集型任务 2 是 CPU密集型任务。再简单一点就是你的任务是需要数据的还是需要计算的。需要数据的就是IO,需要计算的就是CPU, 根据这两种情况来指定我们的资源分配。推荐一篇文章https://blog.csdn.net/youanyyou/article/details/78990156

合理的资源分配,可以将系统的性能发挥的更好,反之更坏。所以线程不是创建的越多越好。

线程池的线程复用,根据资源合理的分配线程数,都可以帮我们有效的解决资源问题。线程数的大小设置。

建议

CPU密集型任务,最佳线程数设置为 CPU数 1

IO密集型任务, 最佳线程数目 = ((线程等待时间 线程CPU时间)/ 线程CPU时间 )* CPU数目

0 人点赞