首页 > 代码库 > JAVA多线程入门

JAVA多线程入门

   

为什么使用多线程

  • 进程之间不能共享内存,但线程之间共享内存很容易

  • 系统创建进程需要为该进程重新分配系统资源,但创建线程代价小得多,因此使用多线程来实现多任务并发比多进程的效率高

  • JAVA内置了多线程功能支持,而不是单纯的作为底层操作系统的调度方式,从而简化了JAVA的多线程编程

线程的创建

  • 继承Thread类(可直接使用this关键字获得当前对象,多个线程无法共享线程类的实例变量)

  • 实现Runnable接口(必须使用Thread.currentThread()方法,多个线程可以共享线程类的实例变量)

  • 使用CallableFuture创建线程(call()方法作为线程执行体,可以有返回值去,可以声明抛出异常)

线程的生命周期

  • 新建(New)--使用new关键词新建一个线程

  • 就绪(Runnable)--调用start()方法

  • 运行(Running)--处于就绪状态的线程获得CPU,开始执行run()方法体

  • 阻塞(Blocked)
    线程调用sleep()方法主动放弃所占用的处理器资源
    线程调用了一个阻塞式的IO方法
    线程试图获得一个同步监视器,但该监视器被其他线程所持有
    线程在等待某个通知
    程序调用了线程的suspend()方法将该线程挂起(容易导致死锁)

  • 死亡(Dead)
    run()方法或call()方法执行完成,线程正常结束
    线程抛出一个未捕获的异常
    直接调用该线程的stop()方法来结束该线程(容易导致死锁)

控制线程

  • join()方法--当某个程序执行流中调用其他程序的join()方法时,调用线程被阻塞,直到join()方法加入的join线程执行完为止

  • setDemon()方法--将指定线程设置为守护线程

  • sleep()方法--暂停线程的执行,并进入阻塞状态

  • yield()方法--暂停线程的执行,并进入就绪状态

  • setPriority()方法--改变线程的优先级,让优先级高的线程获得更多的执行机会

线程同步

  • 同步代码块(同步监视器为obj)
    synchronized(obj){ ... }

  • 同步方法(同步监视器为this)
    public synchronized void draw{ }

  • 同步锁(Lock)

    //定义锁对象private final ReentrantLock lock = new ReentrantLock();//加锁lock.lock();//释放锁lock.unlock();
  • 释放同步监视器的锁定

  1. 当前线程的同步方法,同步代码块执行结束

  2. 当前线程在同步方法,同步代码块遇到break,return终止了继续执行

  3. 当前线程在同步方法,同步代码块出现未处理的异常

  4. 当前线程执行同步方法,同步代码块时执行了同步监视器对象的wait()方法

  • 不释放同步监视器的情况

  1. 线程执行同步方法,同步代码块时,程序调用Thread.sleep()Thread.yield()方法来暂停当前线程的执行

  2. 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起

线程通信

  • 传统的线程通信
    对于使用synchronized修饰的同步方法或代码块,借助Object类提供的wait(),notify(),notifyAll()方法

  • 使用Condition控制线程通信
    如果程序显式使用Lock对象保证同步,则使用Condition对象的await(),signal(),signalAll()来控制程序的协调运行

  • 使用阻塞队列(BlockingQueue)控制线程通信
    BlockingQueue接口:put()方法尝试把元素放入队列中,入托队列元素已满,则阻塞该线程,take()方法尝试从队列头部去取出元素,如果队列元素已空,则阻塞该线程

线程池

  • Executors工厂类来产生线程池

    //返回ExecutorService对象的方法newCachedThreadPool()
    newFixedThreadPool(int nThreads)
    newSingleThreadExecutor()//返回ScheduleExecutorService线程池的方法newScheduledThreadPool(int corePoolSize)
    newSingleThreadScheduledExecutor()//生成work stealing池,相当于后台线程池ExecutorService newWorkStealingPool(int parallelism)ExecutorService newWorkStealingPool()
  • 创建Runnable或者Callable实现类的实例

  • 调用ExecutorService对象的submit()方法来提交Runnable或者Callable实例

  • 调用ExecutorService对象的shutdown()方法关闭线程池


  • ForkJoinPool--充分利用多核CPU

  1. 创建ForkJoinPool实例

  2. 创建有继承了返回值的RecursiveTask或无返回值的RecursiveAction实例

  3. 调用ForkJoinPoolsubmit(ForkJoinTask task)submit(ForkJoinAction action)方法来执行指定任务

    线程相关类

  • ThreadLocal
    隔离多个线程的数据共享,从根本上避免多个线程之间对共享资源的竞争

  • 包装线程不安全的集合类
    使用Collections提供的类方法包装

  • 线程安全的集合类

  1. Concurrent开头的集合类

  2. CopyOnWrite开头的集合类

 

JAVA多线程入门