Java多线程 3.线程协作

1.Java多线程-认识Java线程

2.Java多线程-线程安全

3.Java多线程-线程协作

4.Java多线程-线程池

5.Java多线程-栅栏

6.Java多线程-Fork/Join



把方法去和堆的内存看做主内存,栈内存看做线程内存,线程使用主内存数据时先进行load操作,将数据加载到线程内存,使用完后进行save操作,将数据保存到主内存;
【睁大眼】:wait释放锁,sleep不释放锁;类锁(锁方法和代码块)和对象锁(锁方法和代码块)是不同的锁
线程协作指不同线程驱动的任务相互依赖,典型的问题就是生产者-消费者问题,生产者和消费者不停地去更新(存/取)商品,商品就是依赖关系的纽带,商品也是生产者线程和消费者线程共享的资源;
有线程协作一定会有资源共享,有共享就有竞争,有竞争就会有线程安全问题。
AA.wait/notify
wait/notfy和线程安全、线程协作都有关系
wait/notify/notifyAll方法是Object类的实例方法,wait使当前线程进入等待阻塞,notify/notifyAll唤醒其他线程结束等待阻塞;
wait/notify/notifyAll只能在synchronized修饰的代码块中调用,并且调用对象是当前线程持有的锁的对象
wait使当前线程释放持有的锁,释放CPU使用,使当前线程进入等待阻塞;
notify/notifyAll唤醒当前对象上的等待线程,使等待线程进入同步阻塞状态,同步阻塞状态的线程公平获取锁,notify()是随机唤醒单个线程,而notifyAll()是唤醒所有的线程。

说明:
0.wait可以设置超时等待,及设置等待时间,超时后自己进入同步阻塞状态,无需其他线程唤醒
1.一定要获得对象的同步锁,才能执行对象的wait/notify/notifyAll方法,否则IllegalMonitorStateException
2.出错场景1:synchronized(XX.class){wait()} -->> 获得类锁没有取得对象锁
3.出错场景2:synchronized(a){wait()} -->> 获得的是a对象的锁,而不是当前对象this的锁
4 .出错场景3:synchronized(this){a.wait()} -->> 获得的当前对象的锁,而不是a对象的锁

调用线程对象interrupt()方法中断

BB.join和sleep yield方法
join是Thread的实例方法,在线程t1中调用线程t2的join方法,t1释放cpu进入阻塞直到t2线程执行结束,t1继续执行
如果有时间参数,则最多等待t2线程的执行时间
如果join和synchronized同时使用时需要注意,线程t1中调用t2.join方法,t1不释放锁,这很容易死锁
sleep让当前线程休眠参数时间,注意:休眠期间线程不会释放任何锁/监听器,会释放cpu使用
可以while(true){if(null) sleep(100)}
sleep和wait的异同:sleep()睡眠时,保持对象锁,仍然占有该锁,wait()睡眠时,释放对象锁。
wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)
yield为静态方法,线程放弃继续执行,功能类似sleep,不同的是不会进入阻塞,会释放锁,而是进入可执行状态
约束:执行yield只是让线程暂停一下,让系统重新调度,大多数情况,yield后系统会继续选择当前线程执行(所以不好验证)

CC.拥塞队列:BlockingQueue

DD.线程中断:interrupt
每个线程都有一个标志位,标志当前线程是否中断,interrupt设置为中断状态,有实例方法和类方法获取线程的中断状态,,
设置线程的中断标记为true, 注意:只是标记线程的中断标记,线程是否继续基于线程run方法中代码
a.如果线程处于阻塞状态wati/sleep/join时,线程会抛出InterruptException
b.阻塞状态的线程抛出InterruptException时会重置中断标志(标志位false),此时需要在捕获的异常中再次调用interrupt
c.获取中断标志的方法是
c.1 Thread.interrupted():测试当前线程是否已经中断,线程的中断状态 由该方法清除;
c.2 threadObject.isInterrupted():测试线程是否已经中断。线程的中断状态 不受该方法的影响。
中断的使用场景2中
1.线程阻塞时,用于中断阻塞状态
2.线程正常运行时,用于线程之间通信(可视变量),告知线程已经中断
终止线程:有三种方法可以使终止线程 1.使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。2.使用stop()方法强行终止线程(不推荐,可能发生不可预料的结果)。3.使用interrupt方法中断线程。

猜你喜欢

转载自www.cnblogs.com/gongcong/p/9265280.html