美文网首页
JavaSE进阶 多线程

JavaSE进阶 多线程

作者: 扶光_ | 来源:发表于2023-10-08 21:33 被阅读0次

    多线程

    指从软硬件上实现多条执行流程的技术

    如12306的买票系统,多个用户同时购票时,每个用户都有一个执行流程。或者百度网盘中同时上传文件和下载文件

    一,多线程的创建

    方式1 继承Thread类

    通过java.lang.Thread类代表线程
    首先自己创建线程类去继承Thread类,并重写run方法。使用时调用start()方法


    image.png

    缺点:继承Thread类,无法继承其他类不利于扩展

    方式2 实现Runnable接口

    定义一个类来实现Runnable接口,重写run方法,使用时调用start()方法

    runnable
    线程任务类只是实现接口,这样的写法他可以继续继承类和实现接口,扩展性好
    缺点多一层对象包装,线程执行结果不可以直接返回

    方式1和方式2他们重写run方法是无返回值的,不适合返回线程结果的业务场景,只能执行功能。

    方式3 jdk5.0新增 实现Callable接口

    解决得到线程执行结果返回

    • 1 得到任务对象
      • 定义类实现Callable接口,重写call方法,封装要做的事情
      • 用FutrueTask把Callable对象封装成线程任务对象
    • 2 把线程任务对象交给Thread处理
    • 3 调用Thread的start方法启用线程
    • 4 线程调用完毕后,启用FutrueTask的get方法获取任务执行结果


      callable

    二,线程的常用方法

    • Thread.currentThread() 那个线程执行他,就调用那个线程名字
    • setName() 设置线程名字
    • getName()获取线程名字
    • Thread.sleep()当前线程休息多长时间后执行

    三,线程安全

    多个线程同时操作同一个共享资源的时候出现的业务安全问题,称线程安全
    如,银行卡你和你女朋友同时去取钱
    出现原因:
    1 存在多线程并发
    2 同时访问共享资源
    3 修改共享资源

    线程同步可以解决这种安全问题

    让多个线程实现先后顺序依次访问共享资源。

    • 加锁
      把共享资源进行上锁,每次只能一个线程进入访问完毕以后解锁,其他线程才能进来

    • 方式1 同步代码块
      把出现线程安全的核心代码块上锁
      synchronized(锁对象){
      //核心代码块
      }
      //锁对象建议使用共享资源作为锁对象
      //对于实例方法可以使用this
      //对于静态方法建议使用类名.class作为锁对象

    • 方式2 同步方法
      将出现线程安全的核心方法上锁
      修饰符synchronized 返回值类型 方法名(形参){
      //操作共享资源的代码
      }

    • 方式3 Lock锁
      private final Lock lock = new ReentrantLock();//final修饰不可替换
      lock.lock()//上锁
      lock.unlock()//解锁
      最好使用try{}finally{}来使用 ,如出现异常也可以解锁

    四,线程池

    线程池就是一个可以复用线程的技术
    不使用线程池的问题

    用户每发送一个请求,后台就创建一个线程来处理,下次来了新任务还要继续创建新线程,而创建多的线程会影响性能

    如有1万个人来使用这个功能,我们不可能创建1万个线程来解决

    4.1 实现线程池

    线程池接口ExecutorService,需要用ThreadPoolExecutor实现类来实现

    参数说明
    临时线程什么时候创建?
    当新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以临时创建临时线程,即创建

    4.2 线程池处理Runnable任务

    处理Runnable
           //关闭线程池
            es.shutdownNow();//立即关闭,会丢失未执行的任务
            es.shutdown();//等待任务执行完毕后执行
    

    4.2 线程池处理Callable任务

    callable

    4.3 Executor工具类实现线程池

    image.png

    五,定时器

    是一种控制任务延时调用,周期调用

    方式 1 Timer定时器

    缺点:

    • 1 Timer定时器是单线程,处理多个任务按照顺序执行,存在延时与定时器的时间有出入
    • 2 如果某个任务异常会使线程死掉,后续的任务处理不了
     //1 创建timer定时器
            Timer timer = new Timer();
            //2 调用方法,处理定时任务
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行一次");
                }
            },3000,2000);//等3秒开始跑,每2秒执行一次
        }
    

    方式2 ScheduledExecutorService定时器

    基于线程池
    多线程处理多任务,如某一任务有问题不会影响其他任务

     //创建ScheduledExecutorService线程池,做定时器
            ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
            //开始定时任务
            ses.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"第一个任务");
                }
            },0,1000, TimeUnit.SECONDS);//每隔1秒跑一次
        }
    

    并发并行

    正在运行的软件就是一个独立的进程,线程属于进程,多个线程并发与并行是同时进行的。


    并发 (同一时间段,抢占cpu执行自己)

    • cpu同时处理线程的数量是有限的
    • cpu会轮询为系统每个线程服务,切换速度很快,让我们感觉是同时执行的,这就是并发
      在同一时刻,同时有多个线程被cpu处理并执行
      并行(cpu会轮询的执行线程)

    线程的生命周期

    java线程状态有六种,定义在Thread类的内部枚举类

    public class Thread{
        public enum State{
              NEW,//新建
              RUNNABLE.//可运行
              BLOCKED,//上锁
              WAITING,//无线等待
              TIME_WAITING,//计时等待
              TERMINATED;//被终止
    
              }
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    相关文章

      网友评论

          本文标题:JavaSE进阶 多线程

          本文链接:https://www.haomeiwen.com/subject/onwmbdtx.html