多线程的实现
多线程的创建
1、线程继承Thread类,实现run方法
2、线程实现Runnable接口,实现run方法
线程的启动
1、如果该线程继承Thread类,直接调用其start方法
2、如果该线程实现Runnable接口,new 一个Thread类,以该线程类作为初始化参数,然后调用Thread类的start方法:例:
new Thread(new MyThread()).start();
3、如果直接调用run方法,则程序变成串行执行
多线程的通信
实现信息共享的方法
1、使用static变量
2、同一个Runnable类的成员变量
信息共享存在的问题
线程有着自己的工作缓存,可能没办法获取到最新的变量的值
可能存在多个线程对变量进行修改,从而产生错误
信息共享存在问题的解决方案
- 采用volatile关键字来修饰变量
- 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)
- 禁止进行指令重排序。(实现有序性)
- volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性
- 使用synchronized关键字来对关键代码区,或函数进行加锁限制,使得一次只能一个线程进入
对方法进行修饰:
public synchronized void function(){
i++;
}
- 对代码块进行修饰:
synchronized(【对象】){ //获取到对象的线程才能执行该代码块,对象为自定义
for(int j=0;j<1000000;j++){
i++;
}
}
多线程管理
使用ThreadAPI实现线程管理
sheep:睡眠一段时间,时间到了,自定醒来
wait:等待,需要别人唤醒
notify\notifyall:唤醒
join:等待另一个线程结束
interrupt:向一个线程发送中断信号
使用API来实现线程管理容易产生死锁等问题,且经常是被动地暂停和终止,所以可以采用检测变量的方式来进行线程的管理