线程调度:
1:分时调度
轮流平均分配cpu
2:抢占式调度 》java属于抢占式
优先级高的先使用cpu,同一个优先级,随机选择一个执行
主线程:
执行主方法的线程,main()
单线程程序:
java中只有一个线程
执行顺序:JVM虚拟机从main()开始从上到下执行
1:JVM执行main方法,main方法进入栈内存,
2:JVM找到操作系统开辟一条main方法同行cup的执行路径
3:cup就可以通过这个路径执行main方法
4:这个路径有一个名字,叫main(主)线程
创建多线程的方法:
*第一种:创建 Thread类的步骤*
1:继承Thread类,实现run方法,创建Thread类的子类,调用start方法并发执行
(start一个线程只能调用一次,多次调用非法)
多线程执行原理:
run方法压栈(统一线程中执行),单线程执行
start方法,开辟新的栈空间(多线程执行)执行run方法
区别:
互不影响,在不同的栈中执行
Thread类的常用方法:
1. getName() 返回该改线程名称
2. static currentThread() 返回当前正在执行的线程
链式编程 :Thread.currentThread().getName()
设置线程名称:两种方式
3. setName() 改变线程名称
4. Thread(String name) 创建带参构造方法,把线程名称传递给父类,让父类给子线程起名字
5. sleep() 当前毫秒暂停
*尽量使用第二种:实现Runnable接口步骤*
1.创建Runnable接口实现类》
2.实现类中重写run方法,设置线程任务》
3.创建Runnable接口的实现类对象(RunnableImpl)》
4.调用Thread类对象,构造方法中传递实现类对象(RunnableImpl)》
5.调用Thread类中的start方法,开启新的线程执行run方法
原因:
1.避免了单线程的局限性
一个类只能继承一个类,实现Runnable接口,还可以继承其他接口
2.增强了扩展性,降低了耦合性
实现Runnable接口的方式,把设置线程任务和开启新线程进行了分离(解耦)
传递不同事实现类,实现不同的任务
匿名内部类实现多线程的创建:
作用:简化代码
//创建接口对象
new Thread (new Runnable(){
//重写run方法,设置线程任务
@Override
public void run(){
sout("线程一");
}
}).start();
线程安全:
多线程访问了线程共享的数据,会产生线程安全问题(练习: 模仿卖票,一个实现类,多个线程)
解决安全问题:
1:同步代码块
格式 :synchronized(锁对象){
可能出现线程安全的代码
}
同步中的线程,没有执行完毕,不会释放锁
同步外的线程,没有锁进不去,进入阻塞状态
程序重复的判断锁,获取锁,释放锁,会降低程序效率
2:同步方法
格式:修饰符 synchronized 返回值类型 方法名(参数列表){
可能出现线程安全的代码
}
同步方法的锁对象:
默认就是线程的实现类对象 this
静态static同步方法:
锁对象是本类的class属性,也是class文件对象(反射)RunnableImpl.class
3:锁机制 Lock锁
接口 Lock java.until.concurrent.locks
Lock中的方法:
void lock();获取锁
void unlock();释放锁
lock接口的实现类:
java.util.concurrent.locks.ReentrantLock
使用步骤:
1. 成员位置创建ReentrantLock r
2. 可能会出现异常的代码前调用lock()获取 r.lock();
3. 可能会出现异常的代码后调用unlock()释放 r.unlock();
使用try{
代码块;
}catch(){
异常;
}finally{
无论是否出现异常都执行unlock释放锁;保证程序效率
}
线程的六种状态:
新建状态,运行状态,阻塞状态,休眠状态,无限等待状态(需要唤醒),死亡状态
等待唤醒方法:
wait(); 无限等待 在Object类中,用锁对象调用
notify(); 多个等待线程,随机唤醒其中一个线程
notifyAll(); 唤醒所有等待线程
休眠计时等待方法:
sleep(Long m); 毫秒值结束后,进入Runnable/Blocked状态
wait(Long m); 毫秒值结束后,自动醒来
等待唤醒机制:
也是线程之间的通信,有效的利用资源,
案例:
产品,生产者,消费者
产品作为,生产者与消费者,共同的锁对象交替执行,(包子案例)
线程池1.5后: java中的有哪些线程池?
1.newCachedThreadPool
创建一个可缓存线程池程,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2.newFixedThreadPool
创建一个固定线程数 线程池 ,如果达到最大线程数,进入到池中等待空闲
3.newScheduledThreadPool
创建一个定长线程池 ,支持定时及周期性任务执行
4.newSingleThreadExecutor
创建一个单线程化的线程池 ,保证顺序按优先级执行
容器--》集合(ArrayList,HashSet,linkList,HashMap)
java.utils.concurrent.Executors: 线程池的工厂类,用来生产线程池
Executors类中的静态方法:
static ExecutorService newFixedThreadPool(int threadNumbers) 可用的固定线程数的线程池
参数:线程数
返回值:ExecutorService接口,面向接口编程
java.utils.concurrent.ExecutorService: 线程池接口
submit(Runnable task); 获取线程,执行线程任务,相当于start方法
void shutdown(); 关闭销毁线程池