1、1,Java多线程机制,2,讲课提纲,1.1 Java中的线程 1.2 Thread的子类创建线程 1.3 使用Runable接口 1.4 线程的常用方法,3,引言,Java语言的一大特性点就是内置对多线程的支持。多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况。Java虚拟机负责管理线程,多个线程将被轮流执行,使得每个线程都有机会使用CPU资源。 观察代码:class A public static void main(String args) while(true) System.out.println(“hello”);while(true) System.out.pri
2、ntln(“hello”);,4,图1.1 JVM让线程轮流执行,线程1,线程2,线程3,JVM,5,1.1 Java中的线程,程序是一段静态的代码,它是应用软件执行的蓝本。 进程是程序的一次动态执行过程,它对应了从代码加载、执行至执行完毕的一个完整过程,这个过程也是进程本身从产生、发展至消亡的过程。线程是比进程更小的执行单位,一个进程在其执行过程中,可以产生多个线程,形成多条执行线索,每条线索,即每个线程也有它自身的产生、存在和消亡的过程,也是一个动态的概念。,6,图1.2 在主线程和其他线程之间轮流交换,应用程序,主线程,线程,线程,JAVA虚拟机(JVM),7,2.线程的状态与生命周期,
3、Java语言使用Thread类及其子类的对象来表示线程,新建的线程在它的一个完整的生命周期中通常要经历如下的四种状态:(1)新建 (2) 运行(3) 中断 (4) 死亡,8,例1.1,Public class Example9-1 public static void main (String args) Leftand left;Righthand right;left=new Lefthand();/创建线程right=new Righthand();left.start();right.start();for(int i=1;i=6;i=+) System.out.println(“我是
4、主线程”);,9,class Lefthand extends Thread public void run() for (int i=1;i=9;i+)System.out.println(“我是左手线程”); Class Righthand extends Thread public vpid run() for(int i=1;i=9;i+) System.out.println(“我是右手线程”); ,10,3.线程调度与优先级,JMV中的线程调度器负责管理线程,调度器把线程的优先级分为10个级别,分别用Thread类中的类常量表示。每个Java线程的优先级都在常数110之间,即Thr
5、ead.MIN_PRIORITY和Thread.MAX_PRIORITY 之间。 setPriority(int grade) 用于调整线程的优先级。 getPriority( ) 返回线程的优先级。 Java调度器的任务是使高优先级的线程能始终运行,一旦时间片有空,则使具有同等优先级的线程以轮流的方式顺序使用时间片。,11,1.2 Thread的子类创建线程,Java中编程实现多线程应用有两种途径:一种是用Thread类的子类创建线程,另一种是用Thread类创建线程。,12,用Thread类的子类创建线程对象,编写Thread类的子类时,需要重写父类的run方法,其目的是规定线程的具体操作
6、,否则线程就什么也不做,因为父类的run方法中没有任何操作语句。 当JVM将CPU使用权切换给线程时,如果线程是Thread的子类创建的,该类中的run方法就立刻执行,13,1.3 使用Runable接口 1. Runable接口与目标对象,创建线程的另一个途径就是用Thread类直接创建线程对象。使用Thread创建线程对象时,通常使用的构造方法是:Thread(Runnable target),14,例1.2,Class Example 9-4 public static void main (String args) Thread threadA,threadB, threadC. th
7、readD;Target0bject a1=new Target0bject(), /线程的目标对象a2=new Target0bject();threadA=new Thread(a1); /目标对象是a1的线程threadB=new Thread(a2);a1.set Nnmber(10);threadA setName(“add”);threadB setName(“add”);threadC=new Thread(a2);threadD=new Thread(a2);a2.stenumber(-10);threadC.setname(“sub”);threadD.setname(“su
8、b”);,15,threadA.start();threadB.start();threadC.start();threadD.start(); Class Target0bject implements Runnable private int number=0;public void setNumber(int n) number=n; Public void run() while(true)if(Thread.currentThread().getName().equals(“add”) number+;System.out.println(“现在number等于”+number);,
9、16,if (Thread.currentThread().gatName(). Equals(“sub”) number-;System.out.println(“现在number等于”+number); try Thread.sleep(1000);catch(InterruptedException e) ,17,2. 关于run( )方法中的局部变量,对于具有相同目标对象的线程,当其中一个线程享用CPU资源时,目标对象自动调用接口中的run( )方法,这时, run( )方法中的局部变量被分配内存空间,当轮到另一个线程享用CPU资源时,目标对象会再次调用接口中的run( )方法。,18
10、,那么run( )方法中的局部变量会再次分配内存空间。也就是说,已经启动运行了两次,分别运行在不同的线程中。不同线程的方法中的局部变量互不干扰,一个线程改变了自己的方法中局部变量的值不会影响其他线程的方法中的局部变量的值。,19,3. 在线程中启动其他线程,线程通过调用start( )方法将启动该线程,使之从新建状态进入就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的主线程独立开始自己的生命周期了。在前面的例子中,都是在主线程中启动其他线程,实际上也可以在任何一个线程中启动另外一个线程。,20,1.4 线程的常用方法,1start() 线程调用该方法将启动线程,使之从新建状态进入
11、就绪队列排队,一旦轮到它来享用CPU资源时,就可以脱离创建它的线程独立开始自己的生命周期了。,21,2run(),Thread类的run()方法与Runnable接口中的run()方法的功能和作用相同,都用来定义线程对象被调度之后所执行的操作,都是系统自动调用而用户程序不得引用的方法。系统的Thread类中,run()方法没有具体内容,所以用户程序需要创建自己的Thread类的子类,并重写run()方法来覆盖原来的run()方法。当run()方法执行完毕,线程就变成死亡状态。在线程没有结束run( )方法之前,不赞成让线程再调用start( )方法,否则会发生IllegalThreadStat
12、eException异常。,22,3sleep(int millsecond),线程占有CPU期间,执行sleep方法来使自己放弃CPU资源,休眠一段时间。休眠时间的长短由sleep方法的参数决定,millsecond是毫秒为单位的休眠时间。如果线程在休眠时被打断,JVM就抛出InterruptedException异常。因此,必须在trycatch语句块中调用sleep方法。,23,4isAlive(),线程处于“新建”状态时,线程调用isAlive()方法返回false。当一个线程调用start() 方法,并占有CUP资源后,该线程的run()方法就开始运行,在线程的run()方法结束之前
13、,即没有进入死亡状态之前,线程调用isAlive()方法返回true。当线程进入“死亡”状态后(实体内存被释放),线程仍可以调用方法isAlive(),这时返回的值是false。,24,例1.3 Import java.util.*; Public class Example9-8 public static void main (String args ) A a=new A();a.thread.start(); Class A implementa Runnable Thread thread;int n=0;A() thread=new Thread(this); Public voi
14、d run() while(true),25, System.out.println(new Date();n+;tryThread.s;eep(1000);catch(InterruptedException e) if (n=3) thread=new Thread(this);thread.start();if (n=12)return;,26,5currentThread(),currentThread() 方法是Thread类中的类方法,可以用类名调用,该方法返回当前正在使用CPU资源的线程。,27,6interrupt(),intertupt()方法经常用来“吵醒”休眠的线程。当一些线程调用sleep方法处于休眠状态时,一个占有CPU资源的线程可以让休眠的线程调用interrupt 方法“吵醒”自己,即导致休眠的线程发生InterruptedException异常,从而结束休眠,重新排队等待CPU资源。,28,总结,今天学习了JAVA多线程机制。包括 Java中的线程.Thread的子类创建线程.使用Runable接口.线程的常用方法多种相关知识,对我们更好的学习JAVA这门课程又做了很关相关知识学习,为我们以后的学习打下了基础。,29,谢谢!,