一、等待/通知机制的实现
1、wait()的作用是使当前执行代码的线程进行等待,将当前线程放入‘预执行队列’中,并且在wait()所在的代码处停止执行,直到接到通知或者中断为止。注意:在调用wait()之前,线程必须获得该对象的对象级别锁,所以只能在同步方法或者同步块中调用wait()方法。——wait方法使线程停止运行
2、notify()方法也要放在同步方法或者同步块中,在调用前,也要获取该对象级别的锁。该方法用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程,在线程规划器随机挑选一个呈wait状态的线程,对其发出通知notify,在执行notify方法后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取该对象锁,要等到notify方法的线程将程序执行完,也就是推出synchronized代码块后,当前线程才会释放锁,而呈wait状态的线程才可以获取该对象锁。——notify使停止的线程继续运行
3、wait和notify如果没有持有合适的锁,会抛出IllegalMonitorStateException
4、notifyAll()方法可以使正在等待队列中等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态,按照线程优先级运行。
5、wait(long time) 超时自动唤醒(在这段时间内也可以被其他线程唤醒)
6、不能通知过早,应该先执行wait,再执行notify
二、join使用
1、A.join() 使子线程A一直执行到结束,让主线程阻塞
2、join与sleep的区别:join内部调用了wait方法,释放了锁,而sleep却不释放锁
三、ThreadLocal(解决线程之间的隔离性)
1、可以将ThreadLoacl类比喻成全局存放数据的盒子,盒子中可以存储每个线程的私有数据。
四、单例模式
package com.yven.thread;
/**
* DCL 双重检查锁 线程安全 效率高 单例模式
* @author Administrator
*
*/
public class Sington {
private static volatile Sington sington;
private Sington(){}
public static Sington getInstance(){
if(sington == null ){
synchronized(Sington.class){
if(sington == null){
sington = new Sington();
}
}
}
return sington;
}
}
/**
* 饿汉模式 线程安全
* @author Administrator
*
*/
class Sington1{
private static Sington1 sington = new Sington1();
private Sington1(){}
public static Sington1 getInstance(){
return sington;
}
}
/**
* 懒汉模式,非线程安全,需要在getInstance方法中添加synchronized
* @author Administrator
*
*/
class Sington2{
private static Sington2 sington ;
private Sington2(){}
public static Sington2 getInstance(){
if( sington == null){
sington = new Sington2();
}
return sington;
}
}
/**
* 线程安全 ,效率低
* @author Administrator
*
*/
class Sington3{
private static Sington3 sington ;
private Sington3(){}
synchronized public static Sington3 getInstance(){
if( sington == null){
sington = new Sington3();
}
return sington;
}
}
/**
* 线程不安全
* @author Administrator
*
*/
class Sington4{
private static Sington4 sington ;
private Sington4(){}
public static Sington4 getInstance(){
if( sington == null){
synchronized(Sington4.class){
sington = new Sington4();
}
}
return sington;
}
}