Java多线程开发(二)

Java多线程开发(二)

一、多线程并发安全问题
多线程之间存在相互抢占(CPU执行权-随机),抢占发生在代码的每一步,产生错误的数据问题,导致多线程数据并发安全问题。

解决方式——加锁

1、同步代码块锁(互斥锁)
synchronized(锁对象){}
根据锁对象共享进来的线程对象保证在执行代码块内容时不会有抢占
锁对象:一个对象,可以把哪些线程对象共享进来
可以把当前参与的线程对象共享进来的对象
方法区资源(把所有的线程对象都共享)
this(当参与的所有线程对象被Runnable实现类对象共享)
Java多线程开发(二)_第1张图片
2、同步方法锁
根据锁对象共享进来的线程对象保证在执行方法里内容不会有抢占。
锁对象:当在非静态方法上加上锁,默认锁对象就是this
当在静态方法上加上锁,默认锁对象就是当前类.class(方法区资源)
Java多线程开发(二)_第2张图片
同步:在某个时刻只能有一个线程对象拥有资源(没有抢占)
异步:一个资源被多个线程对象来抢占
同步一定是安全的,一步不一定不安全!

死锁—由于锁的嵌套导致锁问题,通过死锁检测来让其中一个线程对象先执行。
Java多线程开发(二)_第3张图片
二、等待唤醒机制(结合锁来使用)
多个线程间的一种协作机制。谈到线程我们经常想到的是线程间的竞争(race),比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制。就好比在公司里你和你的同事们,你们可能存在在晋升时的竞争,但更多时候你们更多是一起合作以完成某些任务。就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify());在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。
wait()与sleep()方法的区别
1、sleep():使用时一定要给定休眠时间,到点自然醒。休眠期间会释放线程对象的CPU的执行权(无论有锁还是没锁都会释放执行权但是如果有锁不会释放锁对象)。定义在Thread类里静态方法。
2、 wait():使用时可以给定等待时间到点自然醒,但是如果没有指定等待时间需要强制进行唤醒。在等待期间释放线程对象的CPU执行权,释放锁对象。定义在Object类里。
六、线程的优先级(一定程度上避免死锁的发生)
java线程可以通过setPriority()方法对其设定一个优先级别,高优先级别的线程比低优先级别的线程有更高的几率得到先执行,优先级可以用0到10的整数表示,0为最低优先级别、10为最高优先级别。当线程调度器决定那个线程需要调度时,会根据这个优先级进行调度选择;
1、Thread类有三个优先级静态常量:
MAX_PRIORITY为10,为线程最高优先级;
MIN_PRIORITY取值为1,为线程最低优先级;
NORM_PRIORITY取值为5,为线程中间位置的优先级。
默认情况下,线程的优先级为NORM_PRIORITY。
2、一般来说优先级别高的线程先获取cpu资源先运行,但特殊情况下由于现在的计算器都是多核多线程的配置,有可能优先级低的线程先执行,具体的执行还是看JVM调度来决定。
七、线程的状态
创建、就绪、执行、阻塞、销毁
八、守护线程
当被守护线程执行结束所有的守护线程随之结束。
当被守护线程出现多个时,所有的被守护线程结束,守护线程随之结束(类加载器—守护线程)。
Java多线程开发(二)_第4张图片
Java多线程开发(二)_第5张图片

你可能感兴趣的:(多线程,java,面试)