多线程实现

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 接口: (了解):创建服务,提交服务,获取结果,关闭服务。

静态代理模式:
  1. 真实对象和代理对象都要实现同一个接口
  2. 代理对象代理真实对象,真实对象只用做自己的事情,不用分心。

好处:代理对象可以做很多真实对象做不了的事情,而真实对象只用专心做自己的事情。


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表达式:让代码更加简洁,避免匿名内部类过多。
  1. lambda表达式只能由一行代码的情况下才能简化成一行,如果有多行的,那就使用代码块包裹。
  2. 为lambda表达式的前提是接口为函数式接口(就是只能有一个抽象的方法)
  3. 多个参数也可以去掉参数的类型,如果要去掉就都去掉。如果有多个参数就需要加上就都加上。
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");
    }
}

思考

有什么想法或心得体会,都可以拿出来分享下。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值