二、多线程存在的问题

多线程存在的问题

多线程运用得好可以大大提高系统的性能。但是使用不当也会对系统造成毁灭性灾难。

  1. 线程安全问题。多个线程操作共享数据时,会产生线程安全问题。导致读取脏数据或者丢失更新等问题
  2. 线程活性问题。由于程序问题导致一个线程一直处于非Runnable状态或者处于Runnable状态但执行的任务没有紧张称为线程活性问题。例如:两个线程,线程1需要先占用锁1,再占用锁2。线程2需要先占用锁2,再占用锁1。这是如果线程1占用了锁1,线程2占用了锁2。他们都占用了对方需要的锁,双方都阻塞等待对方的锁释放,导致死锁。
  3. 上下文切换。线程切换引起的上下文切换,会增加系统消耗。

线程安全问题

线程安全问题是多个线程在操作共享数据引起的。要保证线程安全,就需要保证对共享数据的操作有三个性质:原子性,可见性和有序性。

原子性

原子性是指涉及共享数据的操作对别的线程是不可分割的。即其他线程只能看到该操作未发生或者已经结束。

注意 i++ 并不是原子性操作,i++实际上是一个`read-modify-write`操作。
1. 先读取出i的值
2. 修改i的值
3. 写回内存

可见性

可见性是指一个线程对共享数据修改后,其他线程可以看到修改后的值。

1. 由于java内存模型中,每个线程都有一个工作内存。在对共享数据进行修改和读取时,
是先对工作内存中的数据进行操作。所以其他线程读取的共享变量可能是脏数据,无法保证可见性。
2. 重排序导致的有序性问题也是影响可见性的重要因素。

有序性

JIT编译器(处理器,存储子系统也会有重排序,了解)为了优化系统,会对代码进行重排序。重排序按照as-if-serial语义,保证重排序后在单线程时运行结果是一样的。但是多线程时,无法保证有序性。

线程安全解决方案

多线程安全问题是因为多个线程同时操作共享变量,缺乏同步机制来协调线程间数据的访问和活动。jdk提供了锁,volatile关键字等线程同步机制

猜你喜欢

转载自blog.csdn.net/qq_26680031/article/details/81454051