思维导图多线程笔记 - 幕布 (mubu.com)https://mubu.com/explore/2NwDsLQEbIr#m大纲笔记多线程笔记 - 幕布 (mubu.com)https://mubu.com/explore/2NwDsLQEbIr
使用多线程需要知道的具体知识:
通过多线程的笔记,了解了多线程的大概,整体脉络.
但是想要熟练的运用多线程,且能熟练解决在使用多线程后结果不符合预期的问题,还需掌握以下知识:
1.线程的常用方法
Thread.sleep(毫秒数),让线程休眠,时间到,自动唤醒并继续执行
Thread.currentThread():表示获取当前正在执行的线程对象
public finalboolean isAlive():测试线程是否处于活动状态
getName():获取线程名字
优先级:可以给线程设置优先级,范围是1-10,10优先级最高
setPriority(数字):给线程设置优先级,这里优先级高,并不代表一定先执行,只是增加了抢占到资源的机会
getPriority():获取线程的优先级,
Thread提供了三个优先级常量:
Thread.MAX_PRIORITY=10
NORM_PRIORITY = 5
MIN_PRIORITY = 1
Main方法的优先级,是5
注意: 这里的优先级常量其实其实跟百分比几率一样,抢占CPU时间片的几率,10的几率最大;
yield()与jion()方法的区别yield():当前线程暂停执行,与其他线程同时抢占资源,如果还是自己抢占到,则继续执行后续的代码,如果是其他线程抢占到,则其他线程先执行.
(总而言之:客气一下,资源凭本事抢占)
join():当前线程暂停执行,新加入的线程开始执行,当新线程执行完之后,再执行当前线程
2.线程的终止:
第一种方法:通过给定属性,然后通过控制属性值来破坏继续执行的条件
第二种方法:对于正在执行的线程,interrupt()是给线程设置中断标志.
注意:interrupted()是检测中断并清除中断状态;
isInterrupted()只检测中断。
还有重要的⼀点就是:
interrupted()作⽤于当前线程,
interrupt()和isInterrupted()作⽤于此线程,即代码中调⽤此⽅法的线程
线程代码如下
package cn.sz.gl.test03; public class MyRun2 implements Runnable { @Override public void run() { int i = 0; while(!Thread.interrupted()){ System.out.println("我的线程_"+i); i++; } } }
测试代码如下
package cn.sz.gl.test03; public class Test2 { public static void main(String[] args) { //System.out.println(Thread.interrupted());//默认为false MyRun2 mr = new MyRun2(); Thread th = new Thread(mr); th.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } th.interrupt(); } }
第三种:
如果线程因为执行join(),sleep()或是wait()而进入了阻塞状态,此时要想停止它,可以让它调用interrupt(),程序会抛出InterruptedException异常而被catch()子句捕获,进行处理.
线程代码如下:
package cn.sz.gl.test03; public class MyRun3 implements Runnable { @Override public void run() { int i = 0; while(true){ System.out.println("线程_"+i); i++; try { Thread.sleep(500); } catch (InterruptedException e) { break; } } } }
测试代码如下:
package cn.sz.gl.test03; public class Test3 { public static void main(String[] args) { MyRun3 mr = new MyRun3(); Thread th = new Thread(mr); th.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //当调用interrupt方法时,可以改变interrupted的值 //当th线程中有处理InterruptedException异常的时候,如果该线程调用了interrupt方法,那么该线程会抛出InterruptedException异常 th.interrupt(); } }
线程的同步:
处理多线程的问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这个时候我们就需要线程同步,线程同步其实就是一种等待机制,多个需要同时访问该对象的线程进入这个对象的等待池中,形成队列,等待前面线程使用完成,下一个线程再使用
在Java语言中,引入对象互斥锁的概念,保证共享数据操作的完整性;
每个对象都对应于一个可称为"互斥锁"的标记,这个标记保证在任一时刻,只能有一个线程访问对象;
用关键字synchronized给对象加互斥锁.
避免了条件修改无效
synchronized放在对象前面限制一段代码的执行,其语法如
Object obj = new Object(); ... synchronized(this){//this被加锁,任何其他要锁this的方法和代码块被阻塞. 需要同步的代码; } ... synchronized(obj){//obj被加锁,任何其他要锁obj的代码块被阻塞. 需要同步的代码; }
同步非静态方法:synchronized放在方法声明中,表示整个方法为同步方法,锁定this对象,
同步static方法: synchronized放在static方法声明中,表示锁定该类的class对象(xxx.class,是Class类型的,是描述一个类的信息的对象)
线程阻塞:
同步阻塞
调用sleep(),join()方法的时候,sleep()转为休眠,时间到自动唤醒
wait(),notify()方法配套,转为等待,同时释放资源,通过notify()方法唤醒
yield(),释放资源,与其他线程重新抢占资源,抢到就执行
suspend()和resume(),由jdk1.0提供,jdk1.2之后就被放弃了,它也是让线程暂停,但是它不释放资源,导致死锁出现
线程死锁:
死锁的条件:
1> 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2> 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3> 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占用。
4> 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路
(写出)
我的学习心得:
通过梳理思维导图对多线程的知识整体有了了解,通过对多线程的细节知识的整理让我对多线程的理解加深.脉络更加清晰.嗯总而言之对我的益处很大.