您好,欢迎访问三七文档
JAVA核心技术多线程多线程多线程的概念在Java中实现多线程–Thread类–Runnable接口线程的生命周期和线程状态后台线程线程同步与死锁多线程在Java中实现多线程–Thread类–Runnable接口线程的生命周期和线程状态线程同步与死锁多任务当今的操作系统绝大部分都是基于多任务的操作系统;多任务操作系统的最大特点,是可以同时运行多个程序;由于操作系统支持时间片轮换算法,使得用户感觉多个程序在同时运行,似乎有多个CPU在起作用。线程的概念运行在操作系统之上的每个应用程序,都会占用一个独立的进程(process),而进程内又允许运行多个线程(thread),这意味着一个程序可以同时执行多个任务的功能;在基于线程的多任务的处理环境中,线程是执行特定任务的可执行代码的最小单位;多线程帮助你写出CPU最大利用率的高效程序,因为空闲时间保持最低,这对Java运行的交互式的网络互连环境是至关重要的,例如:网络的数据传输速率远低于计算机的处理能力,在传统的单线程环境中,你的计算机必须花费大量的空闲时间来等待,多线程能够使你充分利用这些空闲时间。进程与线程的区别进程是指系统中正在运行中的应用程序,它拥有自己独立的内存空间;线程是指进程中一个执行流程,一个进程中允许同时启动多个线程,它们分别执行不同的任务;线程与进程的主要区别在于:每个进程都需要操作系统为其分配独立的内存地址空间,而同一进程中的所有线程在同一块地址空间中,这些线程可以共享数据,因此线程间的通信比较简单,消耗的系统开销也相对较小。多线程Java支持编写多线程的程序;多线程最大的好处在于可以同时并发执行多个任务,当程序的某个功能部分正在等待某些资源的时候,此时又不愿意因为等待而造成程序暂停,那么就可以创建另外的线程进行其它的工作;多线程可以最大限度地减低CPU的闲置时间,从而提高CPU的利用率;Java对多线程的支持在Java中实现线程有两种方式,分别是:继承java.lang.Thread类实现java.lang.Runnable接口8Thread类中的常用静态方法java.lang.Thread类用于创建和操作线程,其中包括几个很重要的静态方法,用于控制当前线程:9方法原型说明staticThreadcurrentThread()返回对当前正在执行的线程对象的引用staticvoidsleep(longmillis)throwsInterruptedException让当前正在执行的线程休眠(暂停执行),休眠时间由millis(毫秒)指定staticvoidsleep(longmillis,intnanos)throwsInterruptedException让当前正在执行的线程休眠,休眠时间由millis(毫秒)和nanos(纳秒)指定staticvoidyield()暂停当前正在执行的线程,转而执行其它的线程staticbooleaninterrupted()判断当前线程是否已经中断主线程任何一个Java程序启动时,一个线程立刻运行,它执行main方法,这个线程称为程序的主线程;也就是说,任何Java程序都至少有一个线程,即主线程;主线程的特殊之处在于:它是产生其它线程子线程的线程;通常它必须最后结束,因为它要执行其它子线程的关闭工作。10主线程示例11publicclassMainThreadDemo{publicstaticvoidmain(String[]args){//获得当前运行的线程ThreadtMain=Thread.currentThread();System.out.println(当前运行的线程是:+tMain);try{for(inti=0;i5;i++){System.out.println(i);Thread.sleep(2000);//使当前线程休眠2秒}}catch(java.lang.InterruptedExceptionie){ie.printStackTrace();}}}线程别名线程优先级线程学名自定义线程在Java中要实现线程,最简单的方式就是扩展Thread类,重写其中的run方法,方法原型如下:publicvoidrun()如:publicclassMyThreadextendsThread{publicvoidrun(){……}}Thread类中的run方法本身并不执行任何操作,如果我们重写了run方法,当线程启动时,它将执行run方法。12Thread类的构造方法Thread类共提供8种构造方法重载,以下是常用的几种:13构造方法说明Thread()创建一个新的线程Thread(Stringname)创建一个指定名称的线程Thread(Runnabletarget)利用Runnable对象创建一个线程,启动时将执行该对象的run方法Thread(Runnabletarget,Stringname)利用Runnable对象创建一个线程,并指定该线程的名称Thread类的常用方法14方法原型说明voidstart()启动线程finalvoidsetName(Stringname)设置线程的名称finalStringgetName()返回线程的名称finalvoidsetPriority(intnewPriority)设置线程的优先级finalintgetPriority()返回线程的优先级案例:泡茶15classBoilThreadextendsThread{//烧开水的线程publicvoidrun(){try{System.out.println(开始烧水...);Thread.sleep(10000);//假设烧水需要10秒System.out.println(水烧开了。);}catch(InterruptedExceptionie){ie.printStackTrace();}}}classWashThreadextendsThread{//洗茶杯的线程publicvoidrun(){try{for(inti=1;i=5;i++){//洗5个茶杯System.out.print(开始洗第+i+个茶杯...);Thread.sleep(1500);//假设每洗一个茶杯需要1.5秒System.out.println(第+i+个茶杯洗干净。);}}catch(InterruptedExceptionie){ie.printStackTrace();}}}publicclassMakeTea{publicstaticvoidmain(String[]args){newBoilThread().start();//启动烧水线程newWashThread().start();//启动洗茶杯线程}}Runnable接口java.lang.Runnable接口中仅仅只有一个抽象方法:publicvoidrun();也可以通过实现Runnable接口的方式来实现线程,只需要实现其中的run方法即可;Runnable接口的存在主要是为了解决Java中不允许多继承的问题;使用Runnable接口可以使语法的自由度更高。16案例:修改后的泡茶案例17classBoilThreadRunnableimplementsRunnable{//烧开水的线程publicvoidrun(){try{System.out.println(开始烧水...);Thread.sleep(10000);//假设烧水需要10秒System.out.println(水烧开了。);}catch(InterruptedExceptionie){ie.printStackTrace();}}}classWashThreadRunnableimplementsRunnable{//洗茶杯的线程publicvoidrun(){try{for(inti=1;i=5;i++){//洗5个茶杯System.out.print(开始洗第+i+个茶杯...);Thread.sleep(1500);//假设每洗一个茶杯需要1.5秒System.out.println(第+i+个茶杯洗干净。);}}catch(InterruptedExceptionie){ie.printStackTrace();}}}publicclassMakeTea{publicstaticvoidmain(String[]args){newThread(newBoilThreadRunnable()).start();//启动烧水线程newThread(newWashThreadRunnable()).start();//启动洗茶杯线程}}线程优先级事实上,计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能执行任务;优先级较高的线程有更多获得CPU的机会,反之亦然;优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级都是5,但是也可以通过setPriority和getPriority方法来设置或返回优先级;Thread类有如下3个静态常量来表示优先级:MAX_PRIORITY:取值为10,表示最高优先级MIN_PRIORITY:取值为1,表示最底优先级NORM_PRIORITY:取值为5,表示默认的优先级18线程优先级示例19classMyThreadimplementsRunnable{//自定义线程,实现Runnable接口publicvoidrun(){StringstrName=Thread.currentThread().getName();for(inti=0;i50;i++){System.out.println(strName+:+i);}}}publicclassThreadPriority{publicstaticvoidmain(String[]args){//三个线程Threadt1=newThread(newMyThread());//第一个自定义线程Threadt2=newThread(newMyThread());//第二个自定义线程Threadtm=Thread.currentThread();//获得当前线程,即主线程t1.setName((t1);t2.setName((t2);tm.setName(tm);//分别设置线程的名称t1.setPriority(Thread.MAX_PRIORITY);//设置线程的优先级t2.setPriority(Thread.MIN_PRIORITY);System.out.println(t1.getName()+的优先级:+t1.getPriority());System.out.println(t2.getName()+的优先级:+t2.getPriority());System.out.println(tm.getName()+的优先级:+tm.getPriority());t1.start();t2.start();StringstrName=tm.getName();for(inti=0;i50;i++){System.out.println(strName+:+i);}}}线程的生命周期线程在它的生命周期中会处于不同的状态:20新线程(新建)就绪运行死亡等待阻塞start()系统调度run()方法执行完毕睡眠挂起sleep()或join()或等待IO同步锁notify()或interupt()解锁线程状态新建状态(New):使用new关键字创建线程对象,仅仅被分配了内存;就绪状态(Ready):线程对象被创建后,等待它的start方法被调用,以获得CPU的使用权;运行状态(Running):执行run方法,此时的线程的对象正占用CPU;睡眠状态(Sleeping):调用sleep方法,线程被暂停,睡眠时间结束后,线程回到就绪状态,睡眠状态的线程不占用CPU;死亡状态(Dead):run方法执行完毕后,线程进入死亡状态;阻塞状态(Blocked):线程由于某些事件(如等
本文标题:4-多线程
链接地址:https://www.777doc.com/doc-3870420 .html