java多线程入门

     2022-03-17     339

关键词:

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多线程入门

JAVA多线程概述为什么使用多线程进程之间不能共享内存,但线程之间共享内存很容易系统创建进程需要为该进程重新分配系统资源,但创建线程代价小得多,因此使用多线程来实现多任务并发比多进程的效率高JAVA内置了多线程... 查看详情

java多线程入门(代码片段)

Java多线程学习(入门)前言目前对于线程的了解仅仅停留在学习python的threading库,很多线程的概念没有真正弄清楚,所以选择来系统性的学习多线程。那么这次选择的是Java的多线程学习,等学完了分析一下Jav... 查看详情

java多线程入门

   为什么使用多线程进程之间不能共享内存,但线程之间共享内存很容易系统创建进程需要为该进程重新分配系统资源,但创建线程代价小得多,因此使用多线程来实现多任务并发比多进程的效率高JAVA内置了多线程... 查看详情

java多线程快速入门

通过继承Thread类来实行多线程packagecom.cppdy;//通过继承Thread类来实行多线程classMyThreadextendsThread{@Overridepublicvoidrun(){for(inti=0;i<30;i++){System.out.println("线程打印:"+i);}}}publicclassThreadDemo{publicstaticvoid 查看详情

java多线程快速入门

//通过实现Runnable接口实现多线程packagecom.cppdy;//通过实现Runnable接口实现多线程classMyThread1implementsRunnable{@Overridepublicvoidrun(){for(inti=0;i<30;i++){System.out.println("线程打印:"+i);}}}publicclassThreadDemo1{pub 查看详情

java多线程快速入门

多线程应用实例(批量发送短信)1、创建实体类packagecom.cppdy;publicclassUserEntity{privateintid;privateStringname;publicintgetId(){returnid;}publicvoidsetId(intid){this.id=id;}publicStringgetName(){returnname;}publicvoidse 查看详情

java多线程快速入门

通过匿名内部类的方法创建多线程packagecom.cppdy;//通过匿名内部类的方法创建多线程publicclassThreadDemo2{publicstaticvoidmain(String[]args){newThread(newRunnable(){@Overridepublicvoidrun(){for(inti=0;i<30;i++){System.out.println(" 查看详情

java多线程快速入门

什么是守护线程  守护线程是为用户线程服务的这么一个线程,主线程结束,守护线程也结束packagecom.cppdy;classMyThread3extendsThread{@Overridepublicvoidrun(){System.out.println("开始执行线程");try{sleep(1000);}catch(Exceptione){}System.out.println("结束... 查看详情

java入门篇13--多线程

多线程是java并发的基础,我们先来学习一下吧:首先,让我们来起一个多线程,看看publicclassHelloWorld{publicstaticvoidmain(String[]args)throwsException{//lambda写法Threadt=newThread(()->{System.out.println("threadstart");try{Thread.sleep(1 查看详情

java多线程快速入门(二十)

1、Java.util的线程安全工具类  Vector(线程安全)    ArrayList(线程不安全)  HashTable(线程安全)  HashMap(线程不安全)2、将线程不安全集合变为线程安全集合packagecom.cppdy;importjava.util.Collections;importjava.util.HashMap;imp... 查看详情

java多线程快速入门

多线程安全问题(卖火车票案例)packagecom.cppdy;classMyThread5implementsRunnable{privateIntegerticketCount=100;@Overridepublicvoidrun(){while(ticketCount>0){try{Thread.sleep(50);}catch(Exceptione){e.printStackTrac 查看详情

java多线程的入门小记

 java的多线程java的多线程的概念,向来都是很复杂、笼统、抽象的。现实世界只有将知识点抽象过后才能有效的传播,但是传播的过程中,只有将抽象的知识点具象化,我们才能习得。所以我们会将个别内容点进行一个具象... 查看详情

java多线程快速入门(十五)

使用violate关键字解决了变量的可见性问题(volatile让多线程刷新falg的值)packagecom.cppdy;classMyThread11extendsThread{//volatile让多个线程刷新falg的值publicvolatilebooleanfalg=true;@Overridepublicvoidrun(){System.out.println("子线程开始执行啦") 查看详情

java多线程快速入门

设置线程优先级:join()packagecom.cppdy;classMyThreadAextendsThread{MyThreadBb;publicMyThreadA(MyThreadBb){this.b=b;}@Overridepublicvoidrun(){try{b.join();sleep(1000);}catch(Exceptione){}System.out.println("A子 查看详情

java入门-高级教程-07.多线程

.../training/java-multi-threading.html更多教程:光束云-免费课程多线程序号文内章节视频1概述-2一个线程的生命周期-3线程的优先级-4创建一个线程-5通过实现Runnable接口来创建线程-6通过继承Thread来创建线程-7通过继承Thread来创建线程-8通... 查看详情

java多线程快速入门

synchonizd解决安全性问题packagecom.cppdy;classMyThread6implementsRunnable{privateIntegerticketCount=100;privateObjectob=newObject();@Overridepublicvoidrun(){while(ticketCount>0){try{Thread.sleep(50);}catc 查看详情

java多线程快速入门(十六)

ThreadLocal关键字实现每个线程有自己的变量packagecom.cppdy;classNumber{privateintnum;publicstaticThreadLocal<Integer>threadLocal=newThreadLocal<Integer>(){@OverrideprotectedIntegerinitialValue(){return0;} 查看详情

java多线程快速入门(十九)

如何停止线程  1、使用stop方法强行终止线程(这个方法不推荐使用,可能会出现业务操作未执行完,线程中断了)packagecom.cppdy;classMyThread15extendsThread{@Overridepublicsynchronizedvoidrun(){while(true){try{wait();}catch(Exceptione){}//如果这里有... 查看详情