zoukankan      html  css  js  c++  java
  • Java多线程

    线程概述

      当一个程序进入内存中,即变成一个进程,进程是处于运行过程中的程序

      并行和并发:

        并行:是同一时刻,有多条指令在处理器上运行

        并发:同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在宏观上具有多个线程同时执行的效果

      多线程的优势:

        。。。。。。。。

    线程的创建和启动:

      1.继承Thread类来创建并启动线程线程:

         继承Thread类,重写run()方法,run()为线程执行体,创建Thread的子类,调用start()方法启动线程

         main()方法代表主线程的执行体

          

        Thread.currentThread():返回当前正在执行的线程的对象(静态方法)

        getName():返回调用该方法的线程名字(实例方法)

        多个线程之间无法共享线程类的实例变量

      

      2.实现Runnable接口创建线程类:

        定义Runnable接口的实现类,并重写run()方法(线程执行体)

        创Runnbale实现类的实例,用此实例作为Thread的target来创建Thread对象

        调用start()方法启动线程

        这种创建线程,多个线程可以共享一个target,即多个线程可以共享同一个线程类的实例变量

      3.使用Callable和Future创建线程:

        Callable的call()方法可以作为线程体来执行,可以有返回值,可以声明抛出异常,**Callable对象不能直接作为Thread的Target()

        Future接口来代表Callable接口的返回值,提供了Future接口的实现类,并实现了Runnable接口--可以作为Thread类的Target

        创建Callable接口的实现类,并实现call()方法,创建Callable实现类的实例,可以通过Lambda的表达式创建callable的对象

        使用FutureTask类来包装Callable对象

        使用FutureTask类的实例作为Thread的target创建线程,调用start()方法启动线程

        FutureTask对象的get()方法来获得返回值

       推荐接口创建线程

    线程生命周期

      新建和就绪状态:

        调用start()方法后线程处于就绪状态,但并没有立即运行,线程何时开始运行由JVM里线程调度器来调度

        不能直接调用run()方法,直接调用run()方法的话还是单线程来的

        不要重复调用start()方法,会抛出IllegalThreadStateException

        如果想调用start()方法后线程立即运行,可以使用Thread.sleep(1)来让当前线程睡眠1毫秒,在这1毫秒内cpu会执行另一个处于就绪状态的线程

      运行和阻塞状态:

        p725页线程状态转换图 

      线程死亡:

        线程体执行结束,调用stop()方法,抛出异常,后处于死亡状态

        线程死亡后不要再调用start()方法

    线程控制:

      join线程:

        当被join的线程调用join后,当前运行的线程会被阻塞,直到被join()的线程执行完/等待到指定时间

      后台线程:调用Thread()对象的setDaemon(true)后将此线程设置成后台线程--又被称为守护线程/精灵线程(设置为后台线程的方法必须在start()前调用)

           如果所有前台线程死亡,后台线程也会自动死亡

         Thread类的isDaemon()方法用来判断线程是否为后台线程

         主线程默认是前台线程,前台线程创建的子线程默认是前台线程,后台线程创建的线程默认为后台线程

      线程睡眠:sleep 静态方法

         线程调用此方法后进入阻塞状态

      

      线程让步:yield 静态方法

         与sleep类似,但只是让当前线程进入就绪状态,等待再次调度,不会阻塞线程(只会给优先级比当前线程高的线程执行机会)

      改变线程优先级:

          setPriority( int k) 1-10 尽量使用提供的静态常量设置优先级

    线程同步

      线程安全问题:取钱问题

      同步代码块:

        两个进程并发修改同一个文件时就有可能出现异常,java引入同步监视器来解决这个问题,通用方法---同步代码块

        synchronized(obj){同步代码块}  obj为同步监视器,****线程开始执行同步代码块前必须要先获得对同步监视器的锁定(任何一个时刻智能有一个线程获得对同步代码的锁定)

        通常使用并发访问的共享资源充当同步监视器

      同步方法:使用synchronized修饰某个方法。则该方法为同步方法

        同步方法可以方便实现线程安全类()

      释放同步监视器的锁定(程序无法显示释放对同步监视器的锁定)

      同步锁(Lock)

        Java5开始提供更强大线程同步机制--通过显式定义同步锁对象来实现同步,同步锁由Lock对象充当

        Lock ReadWriteLock是Java5提供的两个根接口,ReentrantLock(可重入锁)实现了Lock接口, ReentrantReadWriteLock实现了ReadWriteLock接口

        StampedLock类

          加锁  --- 修改 ---释放

     

      死锁:两个线程互相等待对方释放同步监视器

    线程通信

      传统线程通信:使用wait() notify() notifyAll()实现线程同步(为Objectt提供的方法),必须由同步监视器对象来调用这三个方法

      wait()当前线程等待

      notify()唤醒在当前监视器等待的线程,随机的

      notifyAll()唤醒在此同步监视器上等待的所有进程

      使用Condition控制线程通信(在用Lock实现同步的情况下)

        Condition对象被绑定在Lock对象的实例上,通过调用newCondition()获得Condition对象

        Condition对象的await()方法

                signal()

                signalAll() 和传统线程的三个方法类似

      

      使用阻塞队列(BlockingQueue)控制线程通信

        虽然是Queue的子接口,但主要用途是作为线程同步工具

            基于队列的线程控制,尾部放入,头部取出

    线程组和未处理的异常

      ThreadGroup实现对一批线程进行分类管理,Thread在创建的时候可以指定所属的线程组(一旦某个线程加入某个线程组后中途不能更改)

    线程池:

      Executors()工厂来生产线程池 返回ExecutorService对象代表尽快执行的线程池

      线程的创建成本较高,用线程池,线程执行完后不会死亡,而是回到线程池称为空闲状态,等待接收再次执行

      Java8增强的ForkJoinPool:是ExecutorService的实现类,是一种特殊的线程池

        

        

          

         

        

        

        

  • 相关阅读:
    排序算法之直接插入排序
    排序算法之快速排序
    进程内存空间
    python基础13 ---函数模块3(正则表达式)
    python基础12 ---函数模块2
    python基础11 ---函数模块1
    python基础10 ---匿名函数和递归
    python基础9 -----python内置函数2
    python基础8 -----迭代器和生成器
    python基础7 ---python函数
  • 原文地址:https://www.cnblogs.com/xiaochenztx/p/8575099.html
Copyright © 2011-2022 走看看