java---多线程篇(代码片段)

大忽悠爱忽悠 大忽悠爱忽悠     2022-12-22     350

关键词:


进程与线程

进程

  • 当一个程序被运行,就开启了一个进程, 比如启动了qq,word
  • 程序由指令和数据组成,指令要运行,数据要加载,指令被cpu加载运行,数据被加载到内存,指令运行时可由cpu调度硬盘、网络等设备

线程

  • 一个进程内可分为多个线程
  • 一个线程就是一个指令流,cpu调度的最小单位,由cpu一条一条执行指令

并行与并发

并发:单核cpu运行多线程时,时间片进行很快的切换。线程轮流执行cpu

并行:多核cpu运行 多线程时,真正的在同一时刻运行


多线程的创建和启动


run() :存放多线程中运行的代码逻辑

start(): 调用该线程,运行run()方法里面存放的代码


Thread类


创建线程的两种方式

方式一:继承Thread类

public class MyThread extends Thread

    @Override
    public void run() 
        System.out.println("one");
        System.out.println("two");
        System.out.println("three");
    

测试:

public class Main

    public static void main(String[] args)
    
     Thread thread=new MyThread();
     thread.start();
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");
    



当我们调用start()方法开启线程调用后,会执行run里面的代码,此时run方法中运行的代码和主程序中strat后面运行的代码是并行执行的,没先后顺序,是异步执行

但是对于单个线程来将,他的代码执行顺序是固定的


方式二 :实现Runnable接口


Runnable 接口是一个函数式接口,因此我们可以使用lambda表达式

@FunctionalInterface
public interface Runnable 
    public abstract void run();

代码实现:

     Thread thread1=new MyThread();
     //开启线程1
     thread1.start();
     //开启线程2
        Thread thread2=new Thread(()->
            System.out.println("run1");
            System.out.println("run2");
            System.out.println("run3");
        );
        thread2.start();
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");


此时是在一个进程中,有两个分支线程和主进程并行执行,三者互不干扰,执行顺序也不固定


指定线程的名称,并获取

public class Main

    public static void main(String[] args)
    
     Thread thread1=new MyThread();
     //开启线程1
     thread1.start();
     //开启线程2
        Thread thread2=new Thread(()->
            System.out.println("当前线程: "+Thread.currentThread().getName()+"  run1");
            System.out.println("当前线程: "+Thread.currentThread().getName()+"  run2");
            System.out.println("当前线程: "+Thread.currentThread().getName()+"  run3");
        ,"run线程");
        thread2.start();
        System.out.println("1");
        System.out.println("2");
        System.out.println("3");
    


继承方式和实现方式的联系和区别


资源共享的案例:

public class MyThread implements Runnable

    int count=1;
    @Override
    public void run() 
        System.out.println(++count);
    

测试:

public class Main

    public static void main(String[] args)
    
     //开启线程2
        Runnable run1=new MyThread();
        Thread thread2=new Thread(run1);
        thread2.start();
        Thread thread3=new Thread(run1);
        thread3.start();
    



共享了run1实现类中的count变量的值


Thread类相关的方法1


演示如果没有设置线程名称的情况下,系统给出的默认线程名称:

     //开启线程2
        Runnable run1=new MyThread();
        Thread thread2=new Thread(run1);
        thread2.start();
        Thread thread3=new Thread(run1);
        thread3.start();
        System.out.println("run1线程的默认名称:"+thread2.getName());
        System.out.println("run2线程的默认名称:"+thread3.getName());


线程的优先级


线程的优先级,就是哪个线程有较大的概率被执行

优先级使用1-10的数组表示,数字越大优先级越高,线程的默认优先级都是5

设置优先级只是增大优先执行当前线程的概率

线程可以划分优先级,优先级高的线程得到的CPU资源比较多,也就是CPU优先执行优先级高的线程对象中的任务。

设置线程优先级有助于帮助线程规划器确定下一次选中哪一个线程优先执行。

演示:

      Thread t1=new Thread(()->
          System.out.println(Thread.currentThread().getName()+": 线程11");
          System.out.println(Thread.currentThread().getName()+": 线程12");
          System.out.println(Thread.currentThread().getName()+": 线程13");
      ,"线程1,优先级为默认级别5");

        Thread t2=new Thread(()->
            System.out.println(Thread.currentThread().getName()+": 线程21");
            System.out.println(Thread.currentThread().getName()+": 线程22");
            System.out.println(Thread.currentThread().getName()+": 线程23");
        ,"线程2,优先级设置为7");
        t2.setPriority(7);
        t1.start();
        t2.start();
         System.out.println("-----------------1");
        System.out.println("-----------------2");
        System.out.println("-----------------3");


Thread相关方法2


yield方法演示:

    public static void main(String[] args) throws InterruptedException 
      Thread t1=new Thread(()->
          System.out.println(Thread.currentThread().getName()+": 线程11");
          Thread.yield();//让当前线程执行到此时,暂停当前线程,将机会让给优先级更高的线程执行
          System.out.println(Thread.currentThread().getName()+": 线程12");
          System.out.println(Thread.currentThread().getName()+": 线程13");
      ,"线程1,优先级为默认级别5");

        Thread t2=new Thread(()->
            System.out.println(Thread.currentThread().getName()+": 线程21");
            System.out.println(Thread.currentThread().getName()+": 线程22");
            System.out.println(Thread.currentThread().getName()+": 线程23");
        ,"线程2,优先级设置为7");
        t2.setPriority(1);
        t1.start();
        t2.start();
        System.out.println("-----------------1");
        System.out.println("-----------------2");
        System.out.println("-----------------3");
    


join方法演示:

      Thread t1=new Thread(()->
          System.out.println(Thread.currentThread().getName()+": 线程11");
          System.out.println(Thread.currentThread().getName()+": 线程12");
          System.out.println(Thread.currentThread().getName()+": 线程13");
      ,"线程1,优先级为默认级别5");

        Thread t2=new Thread(()->
            System.out.println(Thread.currentThread().getName()+": 线程21");
            System.out.println(Thread.currentThread().getName()+": 线程22");
            System.out.println(Thread.currentThread().getName()+": 线程23");
        ,"线程2,优先级设置为7");
        t2.setPriority(1);
        t1.start();
        t2.start();
        System.out.println("-----------------1");
        System.out.println("-----------------2");
        //阻塞当前的main方法,先执行join进行的线程的代码,执行完毕后,继续执行main方法被阻塞的代码
        t2.join();//相当于把t2的run方法中的代码插入到这里执行,相当于是同步执行
        System.out.println("-----------------3");


sleep方法演示:

      Thread t1=new Thread(()->
      
          System.out.println(Thread.currentThread().getName()+": 线程11");
          System.out.println(Thread.currentThread().getName()+": 线程12");
          System.out.println(Thread.currentThread().getName()+": 线程13");
      ,"线程1,优先级为默认级别5");

        Thread t2=new Thread(()->
            try 
                //当前线程睡5秒后,再执行
                Thread.sleep(5000);
             catch (InterruptedException e) 
                e.printStackTrace();
            
            System.out.println(Thread.currentThread().getName()+": 线程21");
            System.out.println(Thread.currentThread().getName()+": 线程22");
            System.out.println(Thread.currentThread().getName()+": 线程23");
        ,"线程2,优先级设置为7");
        t2.setPriority(1);
        t1.start();
        t2.start();
        System.out.println("-----------------1");
        System.out.println("-----------------2");
        System.out.println("-----------------3");



stop方法和isAlive方法演示

      Thread t1=new Thread(()->
      
          System.out.println(Thread.currentThread(<

java总结篇系列:java多线程(代码片段)

多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的。一.线程的生命周期及五种基本状态关于Java中线程的生命周期,首先看一下下面这张较为经典的图:上图中基本上囊括了Java中多线程各重要知识点。掌握了上... 查看详情

java多线程(工具篇)(代码片段)

线程池原理线程池的七大参数详解:intcorePoolSize:该线程池中核心线程数最大值。核心线程:线程池中有两类线程,核心线程和非核心线程。核心线程默认情况下会一直存在于线程池中,即使这个核心线程什... 查看详情

java多线程(基础篇)(代码片段)

...文记录于阿里一群大佬们手码的书:《深入浅出Java多线程》线程与进程的区别:进程是一个独立的运行环境,而线程是在进程中执行的一个任务进程单独占有一定的内存地址空间,所以进程间存在内存隔离,... 查看详情

java多线程(原理篇)(代码片段)

...f1a;由图可知:所有的共享变量都存在主内存中。每个线程都保存了一份该线程使用到的共享变量的副本。如果线程A与线程B之间要通信的话,必须经历下面2个步骤:a.线程A将本地内存A 查看详情

多线程学习(基础篇)(代码片段)

文章目录一、多线程概述1.进程和线程之间的关系2.创建线程的方式3.Thread的几个常见属性4.中断一个线程5.获取当前线程引用6.线程的状态二、线程安全1.演示线程不安全2.如何避免线程安全问题3.synchronized关键字4.Java标准库中的线... 查看详情

多线程学习(基础篇)(代码片段)

文章目录一、多线程概述1.进程和线程之间的关系2.创建线程的方式3.Thread的几个常见属性4.中断一个线程5.获取当前线程引用6.线程的状态二、线程安全1.演示线程不安全2.如何避免线程安全问题3.synchronized关键字4.Java标准库中的线... 查看详情

号称史上最全java多线程与并发面试题总结—基础篇(代码片段)

前言 多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括... 查看详情

(java实习生)每日10道面试题打卡——java多线程篇(代码片段)

...习,祝大家每天进步亿点点!本篇总结的是Java多线程知识相关的面试题,后续会每日更新~1、什么是进程、线程、协程,他们之间的关系是怎样的?进程:本质上是一个独立执行的程序,进程是操作系统资... 查看详情

java面试题超详细整理《多线程篇》(代码片段)

...率:在一个多核CPU的主机上,我们可以创建多个线程,将多个线程分配给不同的CPU去执行,每个CPU执行一个线程,这样就提高了CPU的使用效率。方便进行业务拆分:面对复杂业务模型,可以对业务模块... 查看详情

java面试题超详细整理《多线程篇》(代码片段)

...率:在一个多核CPU的主机上,我们可以创建多个线程,将多个线程分配给不同的CPU去执行,每个CPU执行一个线程,这样就提高了CPU的使用效率。方便进行业务拆分:面对复杂业务模型,可以对业务模块... 查看详情

java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)(代码片段)

个人主页:Java李小立后面会持续更新java面试专栏,请持续关注如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连❤️❤️❤️)面试宝典列表(持续更新):序号内容链接地址1Java基础篇(点击跳转)ja... 查看详情

java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)(代码片段)

个人主页:Java李小立后面会持续更新java面试专栏,请持续关注如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连❤️❤️❤️)面试宝典列表(持续更新):序号内容链接地址1Java基础篇(点击跳转)ja... 查看详情

java总结篇系列:java多线程(代码片段)

多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的。一.线程的生命周期及五种基本状态关于Java中线程的生命周期,首先看一下下面这张较为经典的图:上图中基本上囊括了Java中多线程各重要知识点。掌握了上... 查看详情

java面试题⭐多线程篇⭐(万字总结,带答案,面试官问烂,跳槽必备,建议收藏)(代码片段)

...架篇(点击跳转)java面试宝典-集合框架篇3Java多线程篇(点击跳转)java面试宝典-多线程篇4JVM篇待分享5Spring篇待分享6Mybatis篇待分享7SpringcCloud篇待分享8Redis篇待分享9Mysql篇待分享10dubbo篇待分享11zookeeper篇待分享12... 查看详情

java_多线程并发编程基础篇—thread类中start()和run()方法的区别(代码片段)

1.start()和run()的区别说明start()方法: 它会启动一个新线程,并将其添加到线程池中,待其获得CPU资源时会执行run()方法,start()不能被重复调用。run()方法:它和普通的方法调用一样,不会启动新线程。只有等到该方法执行完... 查看详情

一篇博客带你轻松应对java面试中的多线程与高并发(代码片段)

1. Java线程的创建方式(1)继承thread类thread类本质是实现了runnable接口的一个实例,代表线程的一个实例。启动线程的方式start方法。start是一个本地方法,执行后,执行run方法的代码。(2)实现runnable... 查看详情

java并发系列终结篇:彻底搞懂java线程池的工作原理(代码片段)

多线程并发是Java语言中非常重要的一块内容,同时,也是Java基础的一个难点。说它重要是因为多线程是日常开发中频繁用到的知识,说它难是因为多线程并发涉及到的知识点非常之多,想要完全掌握Java的并发相... 查看详情

多线程(代码片段)

java多线程经典的生产者/ 消费者实例,线程的协调。1packagejava语言程序设计进阶篇;23importjava.util.concurrent.ExecutorService;4importjava.util.concurrent.Executors;5importjava.util.concurrent.locks.Condition;6importjava.util.co 查看详情