多线程
jvm就是一个进程:
守护线程(垃圾回收),主线程(main函数)
一、线程概述
-进程:一个在内存中运行的应用程序。
-线程:进程上的一个执行单元,一个进程可以有多个线程。
-多进程:在操作系统中同时运行多个程序。
-多线程:在同一应用程序中有多个执行单元同时执行
-线程的生命周期:—个线程从创建到执行完的整个过程
多线程能解决什么问题:多线程能并发执行程序,提高程序的运行效率。
二、如何创建线程对象:
第一种方法:继承Thread类:创建一个线程的子类去继承线程类,因为线程类没有实现类,无法实现功能。同时子类需要重写run()
方法。想要线程跑起来,代码必须写在run()
方法中。
开启线程用start()方法。
public class ThreadDemo01 {
public static void main(String[] args) {
//创建线程对象
ThreadImpl thread = new ThreadImpl();//新建状态
//开启线程,会让线程进入就绪状态
thread.start();//就绪状态 拥有争夺CPU时间片的权利
for (int i = 0;i<10;i++){
System.out.println("主线程"+i);
try {
//sleep不针对的是当前线程
Thread.sleep(100);//睡眠时处于阻塞状态 释放时间片
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ThreadImpl extends Thread{
@Override
public void run() {//执行到run方法 多线程处于运行状态
for (int i = 0;i<10;i++){
System.out.println("分支线程"+i);
}
}
}
第二种方法:实现Runnable接口
/**
* 创建线程的第二种方式,实现Runnable接口
* 实现接口Runnable的类所创建的对象不是线程对象,创建线程对象:Thread thread1 = new Thread(new CreateThread01());
*/
public class ThreadDemo03 {
public static void main(String[] args) {
//创建线程对象
Thread thread1 = new Thread(new CreateThread01());
Thread thread2 = new Thread(new CreateThread01());
Thread thread3 = new Thread(new CreateThread01());
thread1.start();
thread2.start();
thread3.start();
}
}
class CreateThread01 implements Runnable{//实现了Runnable接口,但并不是线程类
@Override
public void run() {
}
}
第三种:通过匿名内部类的方式创建线程对象
/**
* 通过匿名内部类的方式创建线程对象
*/
public class ThreadDemo04 {
public static void main(String[] args) {
//创建线程对象
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
}
});
thread.start();
}
}
三、线程的生命周期
1、新建状态:线程对象被创建
2、就绪状态:线程对象调用start方法后就会处于就绪状态,拥有争夺cpu时间片的权利
3、运行状态:当某一个线程争夺到cpu使用权后,就会执行run方法,执行run方法时就处于运行状态
4、阻塞状态:当某一个线程处于运行态时,发生了睡眠sleep或者控制台打印等需要等待的操作,这时线程就会纳入阻塞状态,释放cpu使用权
5、死亡状态:当run方法执行结束后,即死亡状态。
四、线程在jvm内存上的分布
1、每一个线程对应一个栈(如主线程main占用一个栈)
2、栈的资源是不共享的
3、堆的资源是共享的,因为new出的对象都在堆中开辟空间,堆只有一个。
五、线程调度模型
抢占式调度模型,优先级高的线程抢到cpu时间片的概率更高。Java就是抢占式。
均分式调度模型,平均分配时间片。
Java中线程优先级默认为5.所有线程争夺CPU的概率相同。
六、yield() 让位方法
暂停当前正在执行的线程对象,并执行其他对象
yield()方法的执行会让当前线程从运行状态回到就绪状态。