1.多线程:并发实现
主线程和子线程并行实现。
一个进程中有多个线程,可以同时进行多个任务。进程是系统分配的,线程的执行是由调度器决定的。
注意:线程开启不一定执行,由Cpu调度执行。
线程创建的三种方式:
Thread 类型:
子类继承Thread类,并重写了run方法,然后实例化子类然后调用start()方法。 会让多个子线程同时进行。
package com;/*** @author Lenovo* @date 2024/3/11* @time 8:49* @project Chapter01_Java_多线程**//*1. 实现线程的第一种方式: 集成Thread类2. 然后new一个子类的对象,然后调用start方法;*/
public class ThreadTest01 extends Thread{@Overridepublic void run() {for (int i = 0; i <100 ; i++) {System.out.println(i+"--我在写代码");}}//主线程main 和子线程threadTest01同时执行;public static void main(String[] args) {ThreadTest01 threadTest01 = new ThreadTest01();threadTest01.start();for (int i = 0; i <200 ; i++) {System.out.println(i+"**我在看书,别打扰我");}}}0**我在看书,别打扰我
1**我在看书,别打扰我
2**我在看书,别打扰我
3**我在看书,别打扰我
4**我在看书,别打扰我
5**我在看书,别打扰我
6**我在看书,别打扰我
7**我在看书,别打扰我
8**我在看书,别打扰我
9**我在看书,别打扰我
10**我在看书,别打扰我
11**我在看书,别打扰我
12**我在看书,别打扰我
13**我在看书,别打扰我
0--我在写代码
1--我在写代码
2--我在写代码
3--我在写代码
4--我在写代码
5--我在写代码
6--我在写代码
14**我在看书,别打扰我
15**我在看书,别打扰我
16**我在看书,别打扰我
17**我在看书,别打扰我
18**我在看书,别打扰我
Runnable 接口: (推荐使用)
实现:实现Runnable接口,重写run方法。然后实例化一个Runnable接口对象类,再实例化一个Thread()类,传入Runnable类的实例化对象。最后调用start()方法。
优势:避免单继承的局限性,可以一个对象被多个线程使用。
package com;/*** @author Lenovo* @date 2024/3/11* @time 9:02* @project Chapter01_Java_多线程**//** 1. 实现Runnable接口,并重写run方法2. 实例化runnbale的子类,传入到Thread实例化类种,并调用start方法;
*/
public class RunnableTest01 implements Runnable{@Overridepublic void run() {for (int i = 0; i < 200; i++) {System.out.println(i+"--我在写代码");}}public static void main(String[] args) {RunnableTest01 runnableTest01 = new RunnableTest01();new Thread(runnableTest01).start();//传入runnable的实例化,调用start方法for (int i = 0; i <500 ; i++) {System.out.println(i+"***我在看书,别打扰我");}}
}0***我在看书,别打扰我
0--我在写代码
1***我在看书,别打扰我
1--我在写代码
2***我在看书,别打扰我
2--我在写代码
3***我在看书,别打扰我
3--我在写代码
4***我在看书,别打扰我
4--我在写代码
5***我在看书,别打扰我
5--我在写代码
6***我在看书,别打扰我
6--我在写代码
7***我在看书,别打扰我
7--我在写代码
8***我在看书,别打扰我
9***我在看书,别打扰我
10***我在看书,别打扰我
11***我在看书,别打扰我
12***我在看书,别打扰我
13***我在看书,别打扰我
14***我在看书,别打扰我
15***我在看书,别打扰我
16***我在看书,别打扰我
17***我在看书,别打扰我
问题:并发条件下,多线程同时访问一个资源,会造成数据紊乱,出现一个资源被多个人占用的问题。典型的买票。
package com;import javax.swing.plaf.synth.SynthOptionPaneUI;/*** @author Lenovo* @date 2024/3/11* @time 9:10* @project Chapter01_Java_多线程**/
public class RunnabTest02 implements Runnable{private int ticket=10;@Overridepublic void run() {while (true){if (ticket<=0){break;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"买了第"+ticket--+"张票");}}public static void main(String[] args) {//一份资源RunnabTest02 runnabTest02 = new RunnabTest02();//可以有多个代理:实现new Thread(runnabTest02,"小明").start();new Thread(runnabTest02,"小芳").start();new Thread(runnabTest02,"黄牛党").start();}
}
龟兔赛跑的例子:
package com;/*** @author Lenovo* @date 2024/3/11* @time 9:39* @project Chapter01_Java_多线程**/
public class Race implements Runnable {private stadia
Callable 接口: (了解):创建服务,提交服务,获取结果,关闭服务。
静态代理模式:
- 真实对象和代理对象都要实现同一个接口
- 代理对象代理真实对象,真实对象只用做自己的事情,不用分心。
好处:代理对象可以做很多真实对象做不了的事情,而真实对象只用专心做自己的事情。
package com;/*** @author Lenovo* @date 2024/3/11* @time 10:31* @project Chapter01_Java_多线程**/
public class StaticProxy {public static void main(String[] args) {//一样的结构: lamda表达式:new Thread(()-> System.out.println("线程开始")).start();new WeddingCompany(new Human()).happyMarry();}
}
//结婚的接口:
interface Marry{void happyMarry();//方法:
}//真实对象
class Human implements Marry{@Overridepublic void happyMarry() {System.out.println("我要结婚了很开心");}
}//代理对象:都实现Marry接口
class WeddingCompany implements Marry{private Marry target;public WeddingCompany(Marry target) {this.target = target;}@Overridepublic void happyMarry() {before(); //结婚之前this.target.happyMarry();after(); //结婚之后}public void before(){System.out.println("结婚之前,布置现场");}public void after(){System.out.println("结婚之后,收尾款");}}
Lambda表达式:让代码更加简洁,避免匿名内部类过多。
- lambda表达式只能由一行代码的情况下才能简化成一行,如果有多行的,那就使用代码块包裹。
- 为lambda表达式的前提是接口为函数式接口(就是只能有一个抽象的方法)
- 多个参数也可以去掉参数的类型,如果要去掉就都去掉。如果有多个参数就需要加上就都加上。
package com;/*** @author Lenovo* @date 2024/3/11* @time 11:39* @project Chapter01_Java_多线程**/
public class LambdaTest01 {// 2. 静态内部类实现:static class love2 implements iLike{@Overridepublic void lambda(int a) {System.out.println(" i love you-->" + a);}}public static void main(String[] args) {//外部类iLike love = new love();love.lambda(2);//静态内部类:love2 love2 = new love2();love2.lambda(3);//3. 局部类:在一个类种还有一个类class love3 implements iLike{@Overridepublic void lambda(int a) {System.out.println(" i love you-->" + a);}}love3 love3 = new love3();love3.lambda(4);// 4. 匿名内部类: 没有类的名称,只能由接口或者父类实现:iLike love4 = new iLike(){@Overridepublic void lambda(int a) {System.out.println(" i love you-->" + a);}};love4.lambda(5);//5. lambda表达式实现:iLike love5=null;love5=(a)->{System.out.println(" i love you-->" + a);};love5.lambda(6);// 6. lambda简化:iLike love6=null;love6=a->{System.out.println(" i love you-->"+ a);};love6.lambda(7);}
}interface iLike{void lambda(int a);
}
//1. 外部类实现:
class love implements iLike{@Overridepublic void lambda(int a) {System.out.println(" i love you-->" + a);}
}
线程停止:不使用JDK内置的stop,而是自己设置一个flag标志位进行线程的停止。
package com;/*** @author Lenovo* @date 2024/3/11* @time 12:13* @project Chapter01_Java_多线程**/
public class StopThread implements Runnable{//设置标志位:private boolean flag=true;@Overridepublic void run() {int i =0;while (flag) {System.out.println("子线程运行了"+i++ + "次");}}//外部停止的方法public void stop(){this.flag=false;}public static void main(String[] args) {//创建线程StopThread thread1 = new StopThread();new Thread(thread1).start();for (int i = 0; i < 1000; i++) {System.out.println("main线程运行了"+i+"次");if( i == 900){thread1.stop(); //让flag为false;子线程结束System.out.println("子线程运行结束");}}}}
线程休眠:
Thread.sleep()方法。 每一个对象都有一把锁,sleep不会释放锁。
、package com;import java.text.SimpleDateFormat;
import java.util.Date;/*** @author Lenovo* @date 2024/3/11* @time 12:32* @project Chapter01_Java_多线程**/
public class ThreadSleep {public static void main(String[] args) throws InterruptedException {//模拟倒计时Date startTime = new Date(System.currentTimeMillis());while (true){//每次休眠1秒:Thread.sleep(1000);String time = new SimpleDateFormat("HH:mm:ss").format(startTime);System.out.println("当前系统时间为:"+time);startTime= new Date(System.currentTimeMillis());}}
}
线程礼让:Thread.yield()方法;礼让不一定成功。
线程强制执行: Thread.join() 方法;
package com;/*** @author Lenovo* @date 2024/3/11* @time 13:16* @project Chapter01_Java_多线程**/
public class ThreadJoin {public static void main(String[] args) throws InterruptedException {VipThread vipThread=new VipThread();Thread thread = new Thread(vipThread);thread.start();//主线程:for (int i = 0; i < 500; i++) {//当主线程执行200次后,子线程进行插队操作;if (i==200){thread.join();//插队}System.out.println("主线程执行:"+i+"次");}}
}class VipThread implements Runnable{@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println("vip插队来了"+i);}}
}
观测线程状态:线程的五种状态:New 、Runnable、BLocked、Waiting、Time_waiting、terminated
线程一旦结束就不能重新开始!!!!!
package com;/*** @author Lenovo* @date 2024/3/11* @time 13:28* @project Chapter01_Java_多线程**/
public class ThreadState {public static void main(String[] args) throws InterruptedException {//子线程:Thread thread = new Thread(()->{for (int i = 0; i < 5; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("///");});Thread.State state = thread.getState();System.out.println("线程的当前状态是:"+state);thread.start();//开始线程:state = thread.getState();System.out.println("线程的当前状态是:"+state);//主线程//如果不是最后结束的状态:while (state != Thread.State.TERMINATED){Thread.sleep(1000);//更新线程状态:state=thread.getState();System.out.println("线程的当前状态是:"+state);}}
}
线程的优先级:优先级高的可能先跑,但不一定会先跑。先设置线程,再start()。一般是5,最高是10。
守护线程:
线程分为用户线程和守护线程。虚拟机必须要等待用户线程执行完毕,不用等待守护线程执行完毕。
package com;/*** @author Lenovo* @date 2024/3/11* @time 13:59* @project Chapter01_Java_多线程**/
public class ThreadDemon {public static void main(String[] args) {God god = new God();user user = new user();//实现Runnable接口:Thread thread = new Thread(god);thread.setDaemon(true);//守护线程启动thread.start();//用户线程启动:new Thread(user).start();}
}//守护线程
class God implements Runnable{@Overridepublic void run() {while (true){System.out.println("守护线程保佑着你。。。");}}
}//用户线程class user implements Runnable{@Overridepublic void run() {for (int i = 0; i < 365000; i++) {System.out.println("我还活着");}System.out.println("结束吧,good bye world");}
}
思考
有什么想法或心得体会,都可以拿出来分享下。