当前位置: 首页 > article >正文

(二十)Java之多线程

目录

1.多线程

2.并发和并行

3.多线程的实现方式

4.Thread类常见成员方法

5.线程的生命周期

​编辑6.线程安全问题(同步代码块)

7.同步方法

8.Lock锁​编辑

9.等待唤醒机制

10.多线程代码思路

11.阻塞队列

12.多线程的六大状态


1.多线程

进程:进程是程序的基本执行实体,可以理解为计算机每开一个软件都是一个进程

线程:操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。

可以把线程简单理解为应用软件中互相独立,可以同时运行的功能

问题1.什么是多线程?
有了多线程,我们就可以让程序同时做多件事情
问题2.多线程的作用?
提高效率
问题3.多线程的应用场景?
只要你想让多个事情同时运行就需要用到多线程,比如:软件中的耗时操作、所有的聊天软件、所有的服务器

2.并发和并行

并发:在同一时刻,有多个指令在单个CPU上交替执行
并行:在同一时刻,有多个指令在多个CPU上同时执行

疑问:电脑CPU不是只有一颗吗?对的,但是CPU分为2核4线程、4核8线程、8核16线程、16核32线程、32核64线程...

3.多线程的实现方式

  • 继承Thread类的方式进行实现
  • 实现Runnable接口的方式进行实现
  • 利用Callable接口和Future接口方式实现
方法1:继承Thread类的方式进行实现
public class MyThread extends Thread{
    @Override
    public void run() {
//书写线程要执行的代码
        for (int i = 0; i < 10; i++) {
            System.out.println(this.getName() + "Hello MyThread");
        }
    }
}

public class ThreadDemo1{
    public static void main(String[] args) {
        MyThread myThread1 = new MyThread();
        MyThread myThread2 = new MyThread();
        myThread1.setName("线程1:");
        myThread2.setName("线程2:");
        myThread1.start();
        myThread2.start();
    }
}
输出结果:交替随机
线程1:Hello MyThread
线程2:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程1:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
线程2:Hello MyThread
线程1:Hello MyThread
方法2:实现Runnable接口的方式进行实现
public class MyRun implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            //获取当前线程的对象,因为此时本类没有继承Thread类
            //所以不能调用getname()方法
            System.out.println(Thread.currentThread().getName() + "Hello Thread");
        }
    }
}

public class ThreadDemo2 {
    public static void main(String[] args) {
        MyRun mr = new MyRun();
        Thread thread1 = new Thread(mr);
        Thread thread2 = new Thread(mr);
        thread1.setName("线程1:");
        thread2.setName("线程2:");
        thread1.start();
        thread2.start();
    }
}

无论是第一种继承Thread类还是第二种实现Runnable接口,其中的方法run()的返回值都是void,所以如果想要得到线程运行的结果就需要用到第三种方法

多线程的第三种实现方式:
特点:可以获取到多线程运行的结果

  1. 创建一个类MyCallable实现callable接口
  2. 重写call() (是有返回值的,表示多线程运行的结果)
  3. 创建MyCallable的对象(表示多线程要执行的任务) 
  4. 创建FutureTask的对象(作用管理多线程运行的结果)
  5. 创建Thread类的对象,并启动(表示线程)
方法3:利用Callable接口和Future接口方式实现
public class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        //求1~100的和
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            sum += i;
        }
        return sum;
    }
}

public class ThreadDemo3{
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //创建MyCallable的对象(表示多线程要执行的任务)
        MyCallable mc = new MyCallable();
        //创建FutureTask的对象(作用管理多线程运行的结果)
        FutureTask<Integer> ft = new FutureTask<>(mc);
        //创建线程的对象
        Thread t1 = new Thread(ft);
        //启动线程
        t1.start();
        //获取多线程运行的结果
        Integer result=ft.get();
        System.out.println(result);
    }
}

4.Thread类常见成员方法

 细节1:如果我们没有给线程设置名字,线程也是有默认的名字的,格式:Thread-x(X序号,从0开始的),比如实例化的第一个线程为Thread-0

细节2:用构造方法设置姓名时,需要继承Thread的对象类重写构造方法,因为构造方法不能继承

细节3:当JVM虚拟机启动之后,会自动的启动多条线程其中,有一条线程就叫做main线程,他的作用就是去调用main方法,并执行里面的代码,我们写的所有的代码其实都是运行在main线程当中

细节4:线程的调度分为抢占式调度(随机)和非抢占式调度,Java中采用的是抢占式,线程优先级1~10十档,默认为5

细节5:final void setDaemon(Boolean on)方法设置为守护线程,当其他的非守护线程执行完毕之后,守线程会陆续结束,相当于是“备胎”,使用场景:聊天框和发送图片,当把聊天框这个线程结束以后,发送图片就没有必要继续执行下去了,执行一段时间可以自动关闭

细节6:出让/礼让线程,Thread.yield(),让线程的执行尽可能均匀,让出当前CPU的执行权

细节7:插入线程join()方法,表示把方法调用者这个线程,插入到当前线程之前

5.线程的生命周期

6.线程安全问题(同步代码块)

案例:多线程卖票,某电影院目前正在上映国产大片,共有100张票,而它有3个窗口卖票,请设计一个程序模拟该电影院卖票

首先要知道一个前提,线程在执行任务的时候,CPU的执行权可能随时会被抢走,所以如果实例化三个对象执行同一段代码就有可能出现第一个对象还没执行到打印语句就被抢走了执行权,那么最简单的想法就是把需要执行的代码“锁起来”,从而引出了——同步代码块,作用:把操作共享数据的代码锁起来

public class MyThread extends Thread{
    表示这个类所有的对象,都共享ticket数据
    static int ticket = 1;
    锁对象一定要是唯一的
    static Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                if(ticket <= 100){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(this.getName() + "正在售卖第" + ticket);
                    ticket++;
                }else {
                    break;
                }
            }
        }
    }
}

public class ThreadDemo1 {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        MyThread t2 = new MyThread();
        MyThread t3 = new MyThread();

        t1.setName("售票窗口1");
        t2.setName("售票窗口2");
        t3.setName("售票窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

7.同步方法

StringBuilder用于单线程情况下,不需要考虑数据安全

StringBuffer用于多线程情况下

8.Lock锁

9.等待唤醒机制

思路分析:此处消费者和生产者的等待和唤醒操作就是机制的原理

10.多线程代码思路

  1. 循环(while true)
  2. 同步代码块synchronized
  3. 判断共享数据是否到了末尾(到了末尾,if...break)
  4. 判断共享数据是否到了末尾(没有到末尾,执行核心逻辑else)

11.阻塞队列

12.多线程的六大状态

在Java虚拟机中没有定义运行状态

线程的状态操作
新建状态(NEW)创建线程对象
就绪状态(RUNNABLE)start()
阻塞状态(BLOCKED)无法获得锁对象
等待状态(WAITING)wait()
计时等待(TIMED WAITING)sleep()
结束状态(TERMINATED)全部代码运行完毕

http://www.kler.cn/news/361630.html

相关文章:

  • babylonjs shader学习之copy shadertoy案例
  • 《重置MobaXterm密码并连接Linux虚拟机的完整操作指南》
  • Java应用程序的测试覆盖率之设计与实现(二)-- jacoco agent
  • Nacos相关问题
  • 图片无损放大工具Topaz Gigapixel AI v7.4.4 绿色版
  • 递归算法之二分搜索(Binary Search)详细解读
  • Matlab 火焰识别技术
  • 基于SpringBoot 4S店车辆管理系统【附源码】
  • 【C++】stack 和 queue
  • Java网络编程-简单的API调用
  • docker-compose-lnmp-wordpress
  • 导出问题处理
  • Facebook封号原因分析及解决办法
  • springboot中service和controller作用
  • #{}和${}
  • TemporalBench:一个专注于细粒度时间理解的多模态视频理解的新基准。
  • 软件开发术语(A开头)---持续更新
  • JavaScript 中,要实现清零操作
  • Leetcode—194. 转置文件【中等】(Shell)
  • 实验:使用Oxygen发布大型手册到Word格式
  • Vlan虚拟局域网
  • 读hunter_bipedal_control-main
  • MySQL事务及实现原理
  • 快速修改DBeaver快捷键设置
  • Jupyter Notebook中 Save and Export Notebook As不显示选项
  • C++ [项目] 飞机大战