多线程及线程通信
---恢复内容开始---
1.多线程单例模式:
单例模式:保证类在内存中只有一个对象
控制类的创建,不让其他类来创建本类对象;private Singleton(){}
在本类创建一个本类私有的对象。不允许外部修改。private Static Singleton s=new Singleton() 或者直接用final修饰,外部通过类名.调用
提供公共的访问方式;public static Singleton getInstance(){retun s)
1.1.单例的实现
(1)饿汉式 (默认没有对象,直接创建) 内存换效率
(2)懒汉式(延迟加载,先声明,没有的时候才创建)效率换内存,多线程还是可能创建多个对象
2Timer
计数器类,在特定时间执行特定任务,或定期重复执行
3.线程通信
多个线程并发执行,cpu默认是随机切换线程,如果希望有规律的执行,可以使用通信。
怎么通信?
通过相同的锁对象的同步代码块,通过用Object中的wait()等待,通过notify()唤醒
再同步代码块中,用哪个锁对象,就用哪个对象调用wait或notify。
wait:当前线程等待
notify:唤醒随机线程
wait和sleep区别
sleep必须传入参数,到了时间自动唤醒。wait可传可不穿,传入参数表示在参数时间结束后等待
sleep方法在同步函数或代码块中,不释放锁,wait释放锁
3.1 互斥锁
同步:使用ReentrantLock类中的lock()和unlock()方法进行同步
通信:
使用ReentrantLock类中的newCondition()方法获取COndition对象
需要等待的时候使用Condition()的await方法,唤醒时候使用signal()方法
不同线程使用不同的Condition,这样就区分需要唤醒的线程
4.线程的物种状态
4.1线程的生命周期
新建 创建线程对象
就绪 线程对象启动,但是还没有获取到CPU的执行权
运行 获取到CPU的执行权
阻塞 没有CPU的执行权,回到就绪
死亡 代码运行完毕,线程消亡
5.线程池
程序启动一个线程成本较高,因为涉及到与操作系统交互,而线程池可以很好的提高性能,尤其是当程序需要 创建 大量生存周期很短的线程时。线程池中每一个线程代码结束后,并不会死亡,而是回到线程池中成为空闲状态,等待 下一个对象来使用。
JDK5开始,java内置支持线程池。
JDK5新增来了一个Executors工厂类来产生线程池,他有一下两种方法
public static ExecutortService newFixedThreadPool(int nThreads)
public Static ExecutorService newSingleThreadExecutor()
这些方法都返回一个ExecutorService对象,该对象表示一个线程池,可以执行Runnable对象和Callable对象代表的线程。
ExecutorService的方法:
步骤:
创建线程池对象
创建Runnable实例
提交Running实例
关闭线程池
4.2Callable 线程的第三种实现方式
Callable 接口类似于 Runnable
,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
方法Api