java多线程机制
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第九章 Java多线程机制 多线程机制
本次课教学目标
了解Java的多线程机制 掌握创建线程的两个方法 熟悉线程的常用方法 掌握线程同步的意义
Java的多线程机制
多线程机制是Java语言的又一重要特征,使用Βιβλιοθήκη Baidu 线程技术可以使系统同时运行多个执行体,加快 程序的响应时间,提高计算机资源的利用率.使 用多线程技术可以提高整个应用系统的性能. 程序,进程与线程的区别:
线程的优先级
线程在创建时,继承了父类的优先级.线程创建 后,可以在任何时刻调用setPriority方法改变线程 的优先级.优先级为1~10,Thread定义了其中3 个常数:
MAX_PRIORITY最大优先级(值为10); MIN_PRIORITY最小优先级(值为1); NORM_PRIORITY默认优先级(值为5)
例3:线程的优先级演示.
class Race extends Thread { public static void main(String args[]) { Race[] runner=new Race[4]; for(int i=0;i<4;i++) runner[i]=new Race( ); for(int i=0;i<4;i++) runner[i].start( ); runner[1].setPriority(MIN_PRIORITY); runner[3].setPriority(MAX_PRIORITY); } public void run( ) { for(int i=0; i<1000000; i++); System.out.println(getName()+"线程的优先级是 线程的优先级是 "+getPriority()+"已计算完毕 已计算完毕!"); 已计算完毕 } }
public static void main(String args[]) { Thread1 threadA = new Thread1("A ", 50); Thread1 threadB = new Thread1("B ", 100); threadA.start(); threadB.start(); } }
线程的状态与生命周期 新建 当一个Thread类或其子类的对象被声明并 创建时,新生的线程对象处于新建状态.此时它 已经有了相应的内存空间和其他资源. 运行 线程创建之后就具备了运行的条件,一旦 轮到它来享用CPU资源时,即JVM将CPU使用权 切换给该线程时,此线程的就可以脱离创建它的 主线程独立开始自己的生命周期了(即run方法执 行的过程). 中断 有4种原因的中断:
class Lefthand extends Thread { public void run() { for(int i=1;i<=9;i++) { System.out.println("我是左手线程 我是左手线程"); 我是左手线程 } } } class Righthand extends Thread { public void run() { for(int i=1;i<=9;i++) { System.out.println("我是右手线程 我是右手线程"); 我是右手线程 } } }
多线程和多任务:多线程和多任务是两个既有联系又有区 别的概念,多任务是针对操作系统而言的,代表着操作系 统可以同时执行的程序个数;多线程是针对一个程序而言 的,代表着一个程序内部可以同时执行的线程个数,而每 个线程可以完成不同的任务.例如Java推出的HotJava浏 览器,你可以一边浏览网页一边下载新网页,可以同时显 示动画和播放音乐. 主线程:当JVM加载代码,发现main方法之后,就会启 动一个线程,这个线程称作"主线程",该线程负责执行 main方法.如果main方法中没有创建其他的线程,那么 当main方法执行完最后一个语句,JVM就会结束我们的 Java应用程序.如果main方法中又创建了其他线程,那 么JVM就要在主线程和其他线程之间轮流切换,保证每个 线程都有机会使用CPU资源,main方法即使执行完最后 的语句,JVM也不会结束我们的程序,JVM一直要等到程 序中的所有线程都结束之后,才结束我们的Java应用程 序.
线程的创建
创建线程的方式有两种: 通过创建Thread类的子类来实现; 通过实现Runnable接口的类来实现.
Thread的子类创建线程 设计Thread的子类,重写父类的run方法 用Thread类或子类创建线程对象 使用start方法启动线程 当JVM将CPU使用权切换给线程时,自动执行run 方法.
例2:将上例改成使用Runnable接口来实现多线程.
class Thread2 implements Runnable { String s; int m, count=0; Thread2(String ss, int mm) { s=ss; m=mm; } public void run() { try { while (true) { System.out.print(s); Thread.sleep(m); if (++count >= 20) break; } System.out.println(s+"has finished !"); } catch (InterruptedException e) {return;} }
线程同步
Java提供了多线程机制,通过多线程的并发运行 可以提高系统资源利用率,改善系统性能.但在有 些情况下,一个线程必须和其他线程合作才能共同 完成任务.线程可以共享内存,利用这个特点可以 在线程之间传递信息. 在Java中,实现同步操作的方法是在共享内存变 量的方法前加synchronized修饰符.在程序运行过 程中,如果某一线程调用经synchronized修饰的方 法,在该线程结束此方法的运行之前,其他所有线 程都不能运行该方法,只有等该线程完成此方法的 运行后,其他线程才能y运行该方法.
线程的常用 方法
start() :线程调用该方法将启动线程,使之从新 建状态进入就绪队列排队,一旦轮到它来享用 CPU资源时,就可以脱离创建它的线程独立开始 自己的生命周期了. run():线程对象被调度之后所执行的操作,由系 : 统自动调用,用户程序不得引用.系统的Thread 类中,run()方法没有具体内容,所以用户程序需 要创建自己的Thread类的子类,并重写run()方法 来覆盖原来的run()方法.当run方法执行完毕,线 程就变成死亡状态.
返回true,否则返回false. 注意:一个已经运行的线程在没有进入死亡状态 时,不要再给线程分配实体.
currentThread():是Thread类中的类方法, :
可以用类名调用,该方法返回当前正在使用CPU 资源的线程.
interrupt():用来"吵醒"休眠的线程. :
例4:有两个线程:student和teacher,其中 student准备睡一小时后再开始上课,teacher在输 出3句"上课"后,吵醒休眠的线程student.
public static void main(String args[]) { Thread2 threadA = new Thread2("A ", 50); Thread2 threadB = new Thread2("B ", 100); Thread threadC=new Thread(threadA); Thread threadD=new Thread(threadB); threadC.start(); threadD.start(); } }
sleep(int millsecond):线程占有CPU期间, :
执行sleep方法来使自己放弃CPU资源,休眠一段 时间.如果线程在休眠时被打断,JVM就抛出 InterruptedException异常.因此,必须在 try~catch语句块中调用sleep方法.
isAlive():线程处于运行状态时, isAlive()方法 :
public void run() { if(Thread.currentThread()==student) { try{ System.out.println(student.getName()+"正在睡觉,不听 正在睡觉, 正在睡觉 课"); Thread.sleep(1000*60*60); } catch(InterruptedException e) { System.out.println(student.getName()+"被老师叫醒了 被老师叫醒了"); 被老师叫醒了 } System.out.println(student.getName()+"开始听课 开始听课"); 开始听课 } else if(Thread.currentThread()==teacher) { for(int i=1;i<=3;i++) { System.out.println("上课 上课!"); 上课 try{ Thread.sleep(500); } catch(InterruptedException e){} } student.interrupt(); //吵醒 吵醒student 吵醒 } } }
程序是一段静态的代码,它是应用软件执行的蓝本. 进程是程序的一次动态执行过程,它对应了从代码加 载,执行至执行完毕的一个完整过程,这个过程也是 进程本身从产生,发展至消亡的过程. 线程是比进程更小的执行单位,一个进程在其执行过程 中,可以产生多个线程,形成多条执行线索,每条线 索,即每个线程也有它自身的产生,存在和消亡的过 程,也是一个动态的概念.
class Thread1 extends Thread { String s; int m, count=0; Thread1(String ss, int mm){ s=ss; m=mm; } public void run() { try { while (true) { System.out.print(s); sleep(m); count++; if (count >= 20) break; } System.out.println(s+"finished !"); } catch(InterruptedException e) {return;} }
public class Example9_9 { public static void main(String args[]) { A a=new A(); a.student.start(); a.teacher.start(); } } class A implements Runnable { Thread student,teacher; A() { teacher=new Thread(this); student=new Thread(this); teacher.setName("王教授 王教授"); 王教授 student.setName("张三 张三"); 张三 }
使用Runnable接口实现多线程 用继承Thread类的子类或实现Runable接口的类 来创建线程无本质区别,但由于Java不支持多重 继承,所以如果一个类必须继承另一个非Thread 类,此时要实现多线程只能通过实现Runnable接 口的方式. 通过Runnable接口实现多线程的方法: Runnable 设计一个实现Runnable接口的类,重写run方 法; 以该类的对象为参数建立Thread类的对象; 调用Thread类对象的start方法启动线程,将执 行权转交到run方法.
CPU资源从当前线程切换给其他线程 执行了sleep(int millsecond)方法 执行了wait()方法 进入阻塞状态
死亡 run方法结束 .
例1:
public class Example9_1 { public static void main(String args[]) { Lefthand left; Righthand right; left=new Lefthand() ; //创建线程 创建线程 right=new Righthand(); left.start(); right.start(); for(int i=1;i<=6;i++) { System.out.println("我是主线程 我是主线程"); 我是主线程 } } }
本次课教学目标
了解Java的多线程机制 掌握创建线程的两个方法 熟悉线程的常用方法 掌握线程同步的意义
Java的多线程机制
多线程机制是Java语言的又一重要特征,使用Βιβλιοθήκη Baidu 线程技术可以使系统同时运行多个执行体,加快 程序的响应时间,提高计算机资源的利用率.使 用多线程技术可以提高整个应用系统的性能. 程序,进程与线程的区别:
线程的优先级
线程在创建时,继承了父类的优先级.线程创建 后,可以在任何时刻调用setPriority方法改变线程 的优先级.优先级为1~10,Thread定义了其中3 个常数:
MAX_PRIORITY最大优先级(值为10); MIN_PRIORITY最小优先级(值为1); NORM_PRIORITY默认优先级(值为5)
例3:线程的优先级演示.
class Race extends Thread { public static void main(String args[]) { Race[] runner=new Race[4]; for(int i=0;i<4;i++) runner[i]=new Race( ); for(int i=0;i<4;i++) runner[i].start( ); runner[1].setPriority(MIN_PRIORITY); runner[3].setPriority(MAX_PRIORITY); } public void run( ) { for(int i=0; i<1000000; i++); System.out.println(getName()+"线程的优先级是 线程的优先级是 "+getPriority()+"已计算完毕 已计算完毕!"); 已计算完毕 } }
public static void main(String args[]) { Thread1 threadA = new Thread1("A ", 50); Thread1 threadB = new Thread1("B ", 100); threadA.start(); threadB.start(); } }
线程的状态与生命周期 新建 当一个Thread类或其子类的对象被声明并 创建时,新生的线程对象处于新建状态.此时它 已经有了相应的内存空间和其他资源. 运行 线程创建之后就具备了运行的条件,一旦 轮到它来享用CPU资源时,即JVM将CPU使用权 切换给该线程时,此线程的就可以脱离创建它的 主线程独立开始自己的生命周期了(即run方法执 行的过程). 中断 有4种原因的中断:
class Lefthand extends Thread { public void run() { for(int i=1;i<=9;i++) { System.out.println("我是左手线程 我是左手线程"); 我是左手线程 } } } class Righthand extends Thread { public void run() { for(int i=1;i<=9;i++) { System.out.println("我是右手线程 我是右手线程"); 我是右手线程 } } }
多线程和多任务:多线程和多任务是两个既有联系又有区 别的概念,多任务是针对操作系统而言的,代表着操作系 统可以同时执行的程序个数;多线程是针对一个程序而言 的,代表着一个程序内部可以同时执行的线程个数,而每 个线程可以完成不同的任务.例如Java推出的HotJava浏 览器,你可以一边浏览网页一边下载新网页,可以同时显 示动画和播放音乐. 主线程:当JVM加载代码,发现main方法之后,就会启 动一个线程,这个线程称作"主线程",该线程负责执行 main方法.如果main方法中没有创建其他的线程,那么 当main方法执行完最后一个语句,JVM就会结束我们的 Java应用程序.如果main方法中又创建了其他线程,那 么JVM就要在主线程和其他线程之间轮流切换,保证每个 线程都有机会使用CPU资源,main方法即使执行完最后 的语句,JVM也不会结束我们的程序,JVM一直要等到程 序中的所有线程都结束之后,才结束我们的Java应用程 序.
线程的创建
创建线程的方式有两种: 通过创建Thread类的子类来实现; 通过实现Runnable接口的类来实现.
Thread的子类创建线程 设计Thread的子类,重写父类的run方法 用Thread类或子类创建线程对象 使用start方法启动线程 当JVM将CPU使用权切换给线程时,自动执行run 方法.
例2:将上例改成使用Runnable接口来实现多线程.
class Thread2 implements Runnable { String s; int m, count=0; Thread2(String ss, int mm) { s=ss; m=mm; } public void run() { try { while (true) { System.out.print(s); Thread.sleep(m); if (++count >= 20) break; } System.out.println(s+"has finished !"); } catch (InterruptedException e) {return;} }
线程同步
Java提供了多线程机制,通过多线程的并发运行 可以提高系统资源利用率,改善系统性能.但在有 些情况下,一个线程必须和其他线程合作才能共同 完成任务.线程可以共享内存,利用这个特点可以 在线程之间传递信息. 在Java中,实现同步操作的方法是在共享内存变 量的方法前加synchronized修饰符.在程序运行过 程中,如果某一线程调用经synchronized修饰的方 法,在该线程结束此方法的运行之前,其他所有线 程都不能运行该方法,只有等该线程完成此方法的 运行后,其他线程才能y运行该方法.
线程的常用 方法
start() :线程调用该方法将启动线程,使之从新 建状态进入就绪队列排队,一旦轮到它来享用 CPU资源时,就可以脱离创建它的线程独立开始 自己的生命周期了. run():线程对象被调度之后所执行的操作,由系 : 统自动调用,用户程序不得引用.系统的Thread 类中,run()方法没有具体内容,所以用户程序需 要创建自己的Thread类的子类,并重写run()方法 来覆盖原来的run()方法.当run方法执行完毕,线 程就变成死亡状态.
返回true,否则返回false. 注意:一个已经运行的线程在没有进入死亡状态 时,不要再给线程分配实体.
currentThread():是Thread类中的类方法, :
可以用类名调用,该方法返回当前正在使用CPU 资源的线程.
interrupt():用来"吵醒"休眠的线程. :
例4:有两个线程:student和teacher,其中 student准备睡一小时后再开始上课,teacher在输 出3句"上课"后,吵醒休眠的线程student.
public static void main(String args[]) { Thread2 threadA = new Thread2("A ", 50); Thread2 threadB = new Thread2("B ", 100); Thread threadC=new Thread(threadA); Thread threadD=new Thread(threadB); threadC.start(); threadD.start(); } }
sleep(int millsecond):线程占有CPU期间, :
执行sleep方法来使自己放弃CPU资源,休眠一段 时间.如果线程在休眠时被打断,JVM就抛出 InterruptedException异常.因此,必须在 try~catch语句块中调用sleep方法.
isAlive():线程处于运行状态时, isAlive()方法 :
public void run() { if(Thread.currentThread()==student) { try{ System.out.println(student.getName()+"正在睡觉,不听 正在睡觉, 正在睡觉 课"); Thread.sleep(1000*60*60); } catch(InterruptedException e) { System.out.println(student.getName()+"被老师叫醒了 被老师叫醒了"); 被老师叫醒了 } System.out.println(student.getName()+"开始听课 开始听课"); 开始听课 } else if(Thread.currentThread()==teacher) { for(int i=1;i<=3;i++) { System.out.println("上课 上课!"); 上课 try{ Thread.sleep(500); } catch(InterruptedException e){} } student.interrupt(); //吵醒 吵醒student 吵醒 } } }
程序是一段静态的代码,它是应用软件执行的蓝本. 进程是程序的一次动态执行过程,它对应了从代码加 载,执行至执行完毕的一个完整过程,这个过程也是 进程本身从产生,发展至消亡的过程. 线程是比进程更小的执行单位,一个进程在其执行过程 中,可以产生多个线程,形成多条执行线索,每条线 索,即每个线程也有它自身的产生,存在和消亡的过 程,也是一个动态的概念.
class Thread1 extends Thread { String s; int m, count=0; Thread1(String ss, int mm){ s=ss; m=mm; } public void run() { try { while (true) { System.out.print(s); sleep(m); count++; if (count >= 20) break; } System.out.println(s+"finished !"); } catch(InterruptedException e) {return;} }
public class Example9_9 { public static void main(String args[]) { A a=new A(); a.student.start(); a.teacher.start(); } } class A implements Runnable { Thread student,teacher; A() { teacher=new Thread(this); student=new Thread(this); teacher.setName("王教授 王教授"); 王教授 student.setName("张三 张三"); 张三 }
使用Runnable接口实现多线程 用继承Thread类的子类或实现Runable接口的类 来创建线程无本质区别,但由于Java不支持多重 继承,所以如果一个类必须继承另一个非Thread 类,此时要实现多线程只能通过实现Runnable接 口的方式. 通过Runnable接口实现多线程的方法: Runnable 设计一个实现Runnable接口的类,重写run方 法; 以该类的对象为参数建立Thread类的对象; 调用Thread类对象的start方法启动线程,将执 行权转交到run方法.
CPU资源从当前线程切换给其他线程 执行了sleep(int millsecond)方法 执行了wait()方法 进入阻塞状态
死亡 run方法结束 .
例1:
public class Example9_1 { public static void main(String args[]) { Lefthand left; Righthand right; left=new Lefthand() ; //创建线程 创建线程 right=new Righthand(); left.start(); right.start(); for(int i=1;i<=6;i++) { System.out.println("我是主线程 我是主线程"); 我是主线程 } } }