好久没看线程的东西了,今天没啥事,回顾一下最最基本的一些知识点。
1:程序、进程、线程的区别?
2:线程的五大状态?
3:创建线程的方式?每种方式的特点?
4:如何控制线程?
0.setPriority(int) 设置线程优先级别 可选范围1-10 默认5
*:优先级高的会更多次的得到时间片
但是绝对无法保证先执行或者先执行完
1.static sleep(long) 让当前线程休眠指定的毫秒数
*:从运行转往阻塞状态 待指定的毫秒数后返回就绪
2.static yield() 让当前线程直接返回就绪状态
*:根本无法保证当前线程一定不先执行~
3.join() 涉及到两个线程
一个线程邀请另一个线程优先执行
在被邀请的线程执行结束之前
邀请别人的线程不再执行 一直阻塞~
*:线程章节中的所有静态方法,都只能操作当前处于运行状态的线程,所以我们需要关注的是方法写在哪,而不是谁调用了。
*:线程中所有涉及到主动进入阻塞的方法(sleep / join)都需要进行异常处理,因为它们都throws InterruptedException
5:线程的一些常用方法?
setName() +getName() : 设置和得到线程的名字
*: 没有枪 没有炮 我们还能自己造
static activeCount() : 得到程序当中活跃线程的总数~
*: 活跃 = 就绪 + 运行 + 阻塞
*: 这个方法永远不可能返回0~
static currentThread() : 得到正在运行状态的线程对象~
*: 这个方法永远不可能出现在run()当中
因为那将完全等价于this
可能出现在两个场景:
1.主方法当中用来得到主线程对象~
2.run()当中调用的其它方法当中 搞清是哪个线程调用的~
setDaemon(true) : 将调用方法的线程设置为守护线程
*: 守护线程 - 为其它线程提供服务的线程
当程序当中只有守护线程的时候守护线程自行结束~
interrupt() : 中断 打断线程的阻塞状态~
*: sleep(long) 或者 join() 都会导致当前线程阻塞
但是 我们能反悔吗?
6:锁
互斥锁 => 互斥锁标记 => 锁标记 => 锁旗标=> 监视器 => monitor
1st way:
synchronized => 修饰符 => 同步的
修饰代码块:
synchronized(临界资源){
需要连续执行的操作1;
需要连续执行的操作2;
需要连续执行的操作3;
}
修饰方法:
public synchronized void add(Objectobj){
...;
}
等价于 从方法第一行到方法最后一行统统加锁
对当前对象this进行加锁~
stu.add() set.add() list.add()
*:如果synchronized修饰静态方法 则相当于对
整个类进行加锁(理解为对.class文件加锁)
*:方法的synchronized特性 不会被继承~ 只能去覆盖
*:StringBuffer + Vector + Hashtable=> synchronized
*:单例模式的懒汉式需要synchronized修饰~
2nd way:
java.util.concurrent.locks.ReentrantLock
lock() 锁
unlock() 释放锁
*:效率更高 功能更强大 更符合OO思想
但是 对程序员要求较高...
互斥锁标记使用过多或者使用不当 就会出现线程相互等待对方释放资源
而又不释放自己的资源给其它线程使用的永久阻塞情况~
如何解决死锁
0.顺序的摆放锁标记的位置 [别想了 这需要改变程序逻辑]
1.线程间相互"通讯" [相互谦让 相互成全彼此]
wait(): 当前线程放弃已经持有的锁标记和时间片
直接进入调用方法的对象的"等待池"当中
notify(): 从调用方法的那个对象的等待池当中
随机的唤醒一个线程
notifyAll(): 从调用方法的那个对象的等待池当中
唤醒所有等待的线程
*:这三个方法都是Object类的方法 所以Java当中每个对象都会
*:这三个方法都必须在已经持有锁标记的情况下使用 =>
所以它们一定会出现在synchronized(xxx){}
否则 程序会出现运行时异常~
锁池和等待池 请问它们有什么相同点和不同点?
进入的时候 是否需要释放资源
锁池不需要释放 才会形成死锁的!
等待池需要释放
出来的时候 是否需要调用代码
锁池不需要
等待池必须要其它线程唤醒(notify() or notifyAll())
出来之后去到哪
锁池回到就绪
等待池直奔锁池!
----------------------------------------------------
已知:Vector类的add() remove() 全是synchronized修饰的
有一个Vector对象叫v
有两个线程对象 t1 和 t2
请问:当t1线程调用v对象的add() 方法开始执行了但是还没执行完成的时候
t2线程能不能调用v对象的add(); 不能
t2线程能不能调用v对象的remove(); 不能
已知:Vector类的add() remove() 全是synchronized修饰的
有两个Vector对象叫v1 和 v2
有两个线程对象 t1 和 t2
请问:当t1线程调用v1对象的add() 方法开始执行了但是还没执行完成的时候
t2线程能不能调用v1对象的add(); 不能
t2线程能不能调用v1对象的remove(); 不能
t2线程能不能调用v2对象的add(); 能
t2线程能不能调用v2对象的remove(); 能