java多线程机制
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("张三 张三"); 张三 }
程序是一段静态的代码,它是应用软件执行的蓝本。 进程是程序的一次动态执行过程,它对应了从代码加 载、执行至执行完毕的一个完整过程,这个过程也是 进程本身从产生、发展至消亡的过程。 线程是比进程更小的执行单位,一个进程在其执行过程 中,可以产生多个线程,形成多条执行线索,每条线 索,即每个线程也有它自身的产生、存在和消亡的过 程,也是一个动态的概念。
线程的优先级
线程在创建时,继承了父类的优先级。线程创建 后,可以在任何时刻调用setPriority方法改变线程 的优先级。优先级为1~10,Thread定义了其中3 个常数:
MAX_PRIORITY最大优先级(值为10); MIN_PRIORITY最小优先级(值为1); NORM_PRIORITY默认优先级(值为5)
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 吵醒 } } }
线程同步
Java提供了多线程机制,通过多线程的并发运行 可以提高系统资源利用率,改善系统性能。但在有 些情况下,一个线程必须和其他线程合作才能共同 完成任务。线程可以共享内存,利用这个特点可以 在线程之间传递信息。 在Java中,实现同步操作的方法是在共享内存变 量的方法前加synchronized修饰符。在程序运行过 程中,如果某一线程调用经synchronized修饰的方 法,在该线程结束此方法的运行之前,其他所有线 程都不能运行该方法,只有等该线程完成此方法的 运行后,其他线程才能y运行该方法。
线程的常用 方法
start() :线程调用该方法将启动线程,使之从新 建状态进入就绪队列排队,一旦轮到它来享用 CPU资源时,就可以脱离创建它的线程独立开始 自己的生命周期了。 run():线程对象被调度之后所执行的操作,由系 : 统自动调用,用户程序不得引用。系统的Thread 类中,run()方法没有具体内容,所以用户程序需 要创建自己的Thread类的子类,并重写run()方法 来覆盖原来的run()方法。当run方法执行完毕,线 程就变成死亡状态。
public static void main(String args[]) { Thread1 threadA = new Thread1("A ", 50); Thread1 threadB = new Thread1("B ", 100); threadA.start(); threadB.start(); } }
返回true,否则返回false。 注意:一个已经运行的线程在没有进入死亡状态 时,不要再给线程分配实体。
currentThread():是Thread类中的类方法, :
可以用类名调用,该方法返回当前正在使用CPU 资源的线程。
interrupt():用来“吵醒”休眠的线程。 :
例4:有两个线程:student和teacher,其中 student准备睡一小时后再开始上课,teacher在输 出3句“上课”后,吵醒休眠的线程student.
例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()+"已计算完毕 已计算完毕!"); 已计算完毕 } }
sleep(int millsecond):线程占有CPU期间, :
执行sleep方法来使自己放弃CPU资源,休眠一段 时间。如果线程在休眠时被打断,JVM就抛出 InterruptedException异常。因此,必须在 try~catch语句块中调用sleep方法。
isAlive():线程处于运行状态时, isAlive()方法 :
线程的创建
创建线程的方式有两种: 通过创建Thread类的子类来实现; 通过实现Runnable接口的类来实现。
Thread的子类创建线程 设计Thread的子类,重写父类的run方法 用Thread类或子类创建线程对象 使用start方法启动线程 当JVM将CPU使用权切换给线程时,自动执行run 方法。
使用Runnable接口实现多线程 用继承Thread类的子类或实现Runable接口的类 来创建线程无本质区别,但由于Java不支持多重 继承,所以如果一个类必须继承另一个非Thread 类,此时要实现多线程只能通过实现Runnable接 口的方式。 通过Runnable接口实现多线程的方法: Runnable 设计一个实现Runnable接口的类,重写run方 法; 以该类的对象为参数建立Thread类的对象; 调用Thread类对象的start方法启动线程,将执 行权转交到run方法。
多线程和多任务:多线程和多任务是两个既有联系又有区 别的概念,多任务是针对操作系统而言的,代表着操作系 统可以同时执行的程序个数;多线程是针对一个程序而言 的,代表着一个程序内部可以同时执行的线程个数,而每 个线程可以完成不同的任务。例如Java推出的HotJava浏 览器,你可以一边浏览网页一边下载新网页,可以同时显 示动画和播放音乐。 主线程:当JVM加载代码,发现main方法之后,就会启 动一个线程,这个线程称作“主线程”,该线程负责执行 main方法。如果main方法中没有创建其他的线程,那么 当main方法执行完最后一个语句,JVM就会结束我们的 Java应用程序。如果main方法中又创建了其他线程,那 么JVM就要在主线程和其他线程之间轮流切换,保证每个 线程都有机会使用CPU资源,main方法即使执行完最后 的语句,JVM也不会结束我们的程序,JVM一直要等到程 序中的所有线程都结束之后,才结束我们的Java应用程 序。
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(); } }
例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;} }
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("我是右手线程 我是右手线程"); 我是右手线程 } } }