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{
@Override
public 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{
@Override
public 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;
@Override
public 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{
@Override
public void happyMarry() {
System.out.println("我要结婚了很开心");
}
}
//代理对象:都实现Marry接口
class WeddingCompany implements Marry{
private Marry target;
public WeddingCompany(Marry target) {
this.target = target;
}
@Override
public 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{
@Override
public 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{
@Override
public void lambda(int a) {
System.out.println(" i love you-->" + a);
}
}
love3 love3 = new love3();
love3.lambda(4);
// 4. 匿名内部类: 没有类的名称,只能由接口或者父类实现:
iLike love4 = new iLike(){
@Override
public 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{
@Override
public 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;
@Override
public 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{
@Override
public 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{
@Override
public void run() {
while (true){
System.out.println("守护线程保佑着你。。。");
}
}
}
//用户线程
class user implements Runnable{
@Override
public void run() {
for (int i = 0; i < 365000; i++) {
System.out.println("我还活着");
}
System.out.println("结束吧,good bye world");
}
}
思考
有什么想法或心得体会,都可以拿出来分享下。