线程的状态:
新生状态:new Thread(),当前线程处于新生状态
就绪状态;start(),这个线程进入到就绪状态,线程准备好可以被cpu调度
运行状态:当cpu调度到这个线程,线程进入到运行状态开始执行
阻塞状态 : 当程序无法正常执行(进入阻塞状态的多种方式...)
终止状态 : 线程结束
注意:
1.一个线程一旦终止,无法恢复
2.一个线程如果进入阻塞状态,阻塞接触会直接恢复到就绪状态
进入到阻塞状态的几种方式 :
1. sleep()
2. join()
3. wait()
4. IO
进入线程就绪状态的方式:
1. start()
2. yield()
3. 线程切换
4. 阻塞接触
进入终止状态的方式:
1.stop 已经过时,不推荐使用 2.正常之间完毕 3.添加标识判断 --> 推荐
sleep(ms) : 1s = 1000ms
线程休眠|睡眠
会进入到阻塞状态,当指定的ms数结束,线程会恢复到就绪状态
抱着资源睡觉
让出cpu的资源
抱着是指对象的资源|锁
作用 :
1) 模拟网络延迟
2) 方法问题的可能性
多线程
三高: 高可用 高性能 高并发
thread 类
线程是程序中执行的线程。 Java虚拟机允许应用程序同时运行多个执行线程。
多线程:
多任务执行,多条路径可以执行
多线程的优点:
提高效率
进程 与 线程 之间的区别:
进程: 系统中的应用程序,一个进程之间包含1~n个线程,进程具有自己的资源,内存空间,进程是资源分配的最小单位
线程: 一个程序中的顺序流,多个线程共享一个进程的资源和数据空间,每一个线程具有自己的程序计数器,线程是cpu调度的最小单位
学习的目标:
1.线程的创建于开启 *****
2.线程的状态 : 新生 就绪 运行 阻塞 终止
3.线程安全 *****
4.线程通信 wait() notify()
线程的创建:
1.继承Thread,重写run()方法,定义线程体 + start()
2.实现Runnable接口,重写run()方法 + start() --> 推荐
3.juc包下Callable接口,重写call()方法
public class Class001_Thread extends Thread{
public static void main(String[] args) {
//创建线程
Class001_Thread th = new Class001_Thread();
//开启线程 start() 可以被cpu调度了
th.start();
for(int i=1;i<=20;i++){
System.out.println("一边讲课....");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//思考:
//1) 不使用start()开启线程,直接调用run()方法
//会出问题,但是不报错
//2)start开启位置是否可以修改?
//可以,但是也是的,会出问题
}
/*
run() 定义线程体
*/
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边喝水....");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
实现Runnable接口,重写run方法+start()
1.类是单继承,接口多实现
2.可以实现资源共享
//创建线程
Thread th = new Thread(new Class002_Thread());
//开启线程
th.start();
//new Class002_Thread().run(); //方法的调用,不是线程的开启
for(int i=1;i<=20;i++){
System.out.println("一边陪女朋友");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/*
定义线程体
*/
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边打游戏");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
同步块
synchronized(对象){
同步代码段;
}
()-->
this
类
资源
注意:
锁不变的内容
自定义引用数据类型对象地址不变
双重检查 double check可以提高效率
public class Class003_Web12306 implements Runnable{
Tickets tickets = new Tickets(); //自定义引用数据类型的对象
public void run() {
//重复买票
while(true){
//同步块
//ABC
if(tickets.num<=0){
break;
}
System.out.println("------------------------");
System.out.println("------------------------");
System.out.println("------------------------");
System.out.println("------------------------");
System.out.println("------------------------");
synchronized (tickets){
//双重检查 double check
if(tickets.num<=0){
break;
}
System.out.println(Thread.currentThread().getName()+"正在购买第"+ tickets.num-- +"张票");
/* try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
}
/*多次购买之间休眠一定时间*/
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Class003_Web12306 web = new Class003_Web12306();
//创建线程
Thread th1 = new Thread(web,"优菈");
Thread th2 = new Thread(web,"魈");
Thread th3 = new Thread(web,"神里绫华");
th1.start();
th2.start();
th3.start();
}
}
//票
class Tickets{
int num = 100;
}
Priority 线程的优先级
线程的优先级越高,有限执行的可能性越大
1~10 线程优先级的数值范围
默认5 NORM_PRIORITY
最小1 MIN_PRIORITY
最大10 MAX_PRIORITY
setPriority(int) 设置一个线程的优先级
getPriority() 获取一个线程的优先级
public class Class006_Priority implements Runnable{
public static void main(String[] args) {
Class006_Priority pri = new Class006_Priority();
Thread th1 = new Thread(pri,"A");
Thread th2 = new Thread(pri,"B");
Thread th3 = new Thread(pri,"C");
th1.setPriority(1);
th3.setPriority(Thread.MAX_PRIORITY);
System.out.println(th1.getPriority());
System.out.println(th2.getPriority());
System.out.println(th3.getPriority());
th1.start();
th2.start();
th3.start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
其他定义线程体的方式
//内部类
static class Inner implements Runnable{
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边吸烟...");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
new Thread(new Inner()).start();
//匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边烫头...");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
//lambda表达式
new Thread(() -> {
for(int i=1;i<=20;i++){
System.out.println("一边洗澡...");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
for(int i=1;i<=20;i++){
System.out.println("一边喝酒...");
try {
Thread.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
yield 礼让线程 高风亮节
当一个线程调用yield,让出cpu的资源,进入到就绪状态
静态方法
public class Class002_Yield implements Runnable{
public static void main(String[] args) {
new Thread(new Class002_Yield(),"A").start();
new Thread(new Class002_Yield(),"B").start();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"开始了");
Thread.yield();
System.out.println(Thread.currentThread().getName()+"结束了");
}
}
join() 插队线程
join(ms) 插队指定的ms数
成员方法join,线程对象.join() 当前线程对象插队
注意: 先就绪,后插队
new Thread(new SHI()).start();
}}
class SHI implements Runnable{
@Override
public void run() {
System.out.println("老王要和老庄决斗!");
System.out.println("老庄接了!!!!!");
//创建老庄线程
Thread t=new Thread(new ZHUANG());
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("老庄不依不饶..继续进攻");
System.out.println("老庄获胜............");
}
}
class ZHUANG implements Runnable{
@Override
public void run() {
System.out.println("老王打了老庄一拳");
System.out.println("老庄中拳了!!!");
for (int i=1;i<=10;i++){
System.out.println("老庄眩晕了"+i+"秒");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("老庄反击了,出拳!");
System.out.println("老王中拳了..流血了");
}
}
void interrupt() 为线程添加一个中断标识
boolean isInterrupted() 测试此线程是否已被中断,是否已经调用过 interrupt()方法添加中断标识,是->true 不是->false
static boolean interrupted() 测试当前线程是否已被中断, 是否已经调用过 interrupt()方法添加中断标识,是->true 不是->false,同时会复位标识
注意: 一个线程如果进入终止状态,线程的中断标识会复位
sleep--> InterruptedException - 如果有任何线程中断了当前线程。
public class Class004_Interrupt implements Runnable{
@Override
public void run() {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=1;i<=100;i++){
if(Thread.interrupted()){
System.out.println("--------->"+Thread.currentThread().isInterrupted());
System.out.println("结束");
break;
}
System.out.println(i);
}
}
public static void main(String[] args) {
Thread th = new Thread(new Class004_Interrupt());
//就绪
th.start();
System.out.println(th.isInterrupted());
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//为th线程添加中断标识
th.interrupt();
System.out.println(th.isInterrupted());
}
}