多线程

多线程

概念

程序

  为了完成某个任务或功能,选择某个编程语言而编写的一组代码指令的集合

进程

  程序的一次运行,是操作系统管理和调度的最小单位,每一个进程之间内存是相互独立的,如果进程之间要通信比较麻烦,可以通过文件,或网络通信方式等

线程

  是进程中的其中一条执行路径,是CPU调度任务的最小单位

  线程是共享同一个进程的内存

如何开启主线程以外的线程

方式一:继承java.lang.Thread类   

  ①继承Thread类
  ②重写public void run(){}编写线程体,即该线程需要完成的任务代码
  ③创建线程对象
  ④启动线程:线程对象.start();

方式二:实现java.lang.Runnable接口

  ①实现java.lang.Runnable接口
  ②实现public void run(){}编写线程体,即该线程需要完成的任务代码
  ③创建线程对象
  ④启动线程:借助Thread类的对象new Thread(自定义线程对象).start();

两种方式的区别

  区别:
  (1)继承Thread类会有单继承的限制 实现Runnable接口不会有单继承的限制
  (2)继承Thread类的方式,共享数据方面比较麻烦,使用static方式 实现Runnable接口,共享数据时,只需要共用同一个的Runnable接口的实现类的对象即可
  (3)继承Thread类的方式,同步的锁的选择要么选择一个static对象作为锁,要么选择“类名.class即当前类Class对象” 实现Runnable接口,同步锁可以直接选择this对象

线程安全问题

前提条件  

  (1)有多个线程
  (2)共享数据
  (3)多条语句操作共享数据

解决方法

  同步synchronized

    形式

//同步代码块
synchronized(锁对象){
    同步代码,即需要加锁的代码
}
//同步方法
synchronized [修饰符] 返回值类型 方法名(形参列表)抛出的异常列表

    同步锁

     (1)任意类型的对象
     (2)保证使用共享数据的多个线程,共用同一个锁对象

    锁的范围 同步代码块:范围

     (1)不能太大:机会不均匀
     (2)不能太小:安全问题没解决
     (3)最好锁一次任务代码

    同步方法的锁:  

      静态方法的锁:当前类的Class对象,即当前类名.class 非静态方法的锁:当前对象,this

线程通信

问题:生产者消费者问题

  问题  现象描述

    有多个线程共享一个缓冲区(例如:数据仓库,文件等),有的线程往里放数据,有的线程往外取数据

    问题有两个

      问题:线程安全问题  因为有共享数据  如何解决:同步

      问题:缓冲区大小有限的  如何解决:线程通信

线程通信的方法

  (1)wait()
  (2)notify()和notifyAll()

    在java.lang.Object   为什么

      线程通信依赖于锁对象,即wait()和notify()是由锁对象调用

      锁对象可能是任意类型的对象,那么这些方法只能在Object类中声明

  面试题:wait()和sleep()的异同?

    同  这两个方法都会导致当前线程从运行状态到阻塞状态

    不同

      从阻塞回到就绪状态

        sleep()睡眠时间到了

        wait()也可以设置时间,但更多时候是通过notify()

      声明的类不同

        wait是Object中,非静态方法

        sleep是Thread类中,静态方法

      锁释放问题

        sleep:不会释放锁的  例如:在卫生间睡着了,锁还在手上

        wait():会释放锁的  例如:抢到锁了,但是因为一些条件不满足,就释放锁,由其他线程执行

java.lang.Thread

方法

  1、获取线程名称的方法  getName()

  2、获取当前线程对象  Thread.currentThread()

  3、线程休眠  Thread.sleep(毫秒)  Thread.sleep(毫秒,纳秒)

  4、线程的优先级

    getPriority()

    setPriority()

      优先级的范围是1-10

      MAX_PRIORITY:10

      MIN_PRIORITY:1

      NORMAL_PRIORITY:5

    注意:业务逻辑不能依赖于优先级

  5、加塞

    join()  这句代码写在那个线程体中,哪个线程被加塞,被调用这个join()的线程加塞

  6、run():所有线程都要写

  7、start():启动线程

生命周期

 

posted @   LuckySnail  阅读(25)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示