Java语言程序设计:第8章 线程
第八章第八章 线程线程JAVA语言程序设计目录目录l多线程编程基础多线程编程基础l线程的生命周期线程的生命周期l线程的优先级线程的优先级l本章小结本章小结28.1 多线程编程基础多线程编程基础l本节内容本节内容线程的概念Thread类Runnable接口线程间的数据共享多线程的同步控制线程之间的通信后台线程38.1.1 线程的概念线程的概念l进程和线程的区别进程和线程的区别l进程进程一个独立程序的每一次运行称为一个进程,例如l用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程设置一个进程要占用相当一部分处理器时间和内存资源大多数操作系统不允许进程访问其他进程的内存空间,进程间的通信很不方便,编程模型比较复杂 多线程编程基础4l线程线程一个程序中多段代码同时并发执行,称为多线程通过多线程,一个进程表面上看同时可以执行一个以上的任务并发创建线程比创建进程开销要小得多,线程之间的协作和数据交换也比较容易Java是第一个支持内置线程操作的主流编程语言多数程序设计语言支持多线程要借助于操作系统“原语(primitives)”8.1.1 线程的概念线程的概念(续续)多线程编程基础58.1.2 Thread类类lThread类类在Java程序中创建多线程的方法之一是继承Thread类 封装了Java程序中一个线程对象需要拥有的属性和方法从Thread类派生一个子类,并创建这个子类的对象,就可以产生一个新的线程。这个子类应该重写Thread类的run方法,在run方法中写入需要在新线程中执行的语句段。这个子类的对象需要调用start方法来启动,新线程将自动进入run方法。原线程将同时继续往下执行Thread类直接继承了Object类,并实现了Runnable接口。它位于java.lang包中,因而程序开头不用import任何包就可直接使用多线程编程基础68.1.2 Thread类类(续续)例例8_1l在新线程中完成计算某个整数的阶乘在新线程中完成计算某个整数的阶乘public class Ex8_1 public static void main( String args ) System.out.println(main thread starts);FactorialThread thread=new FactorialThread(10); thread.start(); System.out.println(main thread ends ); class FactorialThread extends Thread private int num; public FactorialThread( int num ) this.num=num; 多线程编程基础7public void run() int i=num; int result=1; System.out.println(new thread started ); while(i0) result=result*i; i=i-1; System.out.println(The factorial of +num+ is +result); System.out.println(new thread ends); l运行结果运行结果main thread startsmain thread endsnew thread startedThe factorial of 10 is 3628800new thread ends8.1.2 Thread类类(续续)例例8_1运行结果运行结果多线程编程基础8l结果说明结果说明main线程已经执行完后,新线程才执行完main函数调用thread.start()方法启动新线程后并不等待其run方法返回就继续运行,thread.run函数在一边独自运行,不影响原来的main函数的运行l源程序修改源程序修改如果启动新线程后希望主线程多持续一会再结束,可在start语句后加上让当前线程(这里当然是main)休息1毫秒的语句:try Thread.sleep(1); catch(Exception e);8.1.2 Thread类类(续续)例例8_1修改修改多线程编程基础9l修改后运行结果修改后运行结果main thread startsnew thread staredThe factorial of 10 is 3628800new thread endsmain thread endsl运行结果说明运行结果说明新线程结束后main线程才结束8.1.2 Thread类类(续续)例例8_1修改后运行结果修改后运行结果多线程编程基础108.1.2 Thread类类(续续)常用常用API函数函数名称说明public Thread()构造一个新的线程对象,默认名为Thread-n,n是从0开始递增的整数public Thread(Runnable target)构造一个新的线程对象,以一个实现Runnable接口的类的对象为参数。默认名为Thread-n,n是从0开始递增的整数public Thread(String name)构造一个新的线程对象,并同时指定线程名public static Thread currentThread()返回当前正在运行的线程对象public static void yield()使当前线程对象暂停,允许别的线程开始运行public static void sleep(long millis)使当前线程暂停运行指定毫秒数,但此线程并不失去已获得的锁旗标。多线程编程基础11public void start()启动线程,JVM将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程public void run()Thread的子类应该重写此方法,内容应为该线程应执行的任务。public final void stop()停止线程运行,释放该线程占用的对象锁旗标。public void interrupt()打断此线程public final void join()在当前线程中加入调用join方法的线程A,直到线程A死亡才能继续执行当前线程public final void join(long millis)在当前线程中加入调用join方法的线程A,直到到达参数指定毫秒数或线程A死亡才能继续执行当前线程8.1.2 Thread类类(续续)常用常用API函数函数多线程编程基础12public final void setPriority(int newPriority)设置线程优先级public final void setDaemon(Boolean on)设置是否为后台线程,如果当前运行线程均为后台线程则JVM停止运行。这个方法必须在start()方法前使用public final void checkAccess()判断当前线程是否有权力修改调用此方法的线程public void setName(String name)更该本线程的名称为指定参数public final boolean isAlive()测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回true8.1.2 Thread类类(续续)常用常用API函数函数多线程编程基础13l创建创建3个新线程,每个线程睡眠一段时间(个新线程,每个线程睡眠一段时间(06秒),然秒),然后结束后结束public class Ex8_2 public static void main( String args ) /创建并命名每个线程 TestThread thread1 = new TestThread( thread1 ); TestThread thread2 = new TestThread( thread2 ); TestThread thread3 = new TestThread( thread3 ); System.out.println( Starting threads ); thread1.start(); / 启动线程1 thread2.start(); / 启动线程2 thread3.start(); / 启动线程3 System.out.println( Threads started, main endsn ); 8.1.2 Thread类类(续续)例例8_2多线程编程基础14class TestThread extends Thread private int sleepTime; public TestThread( String name ) super( name ); sleepTime = ( int ) ( Math.random() * 6000 ); public void run() try System.out.println( getName() + going to sleep for + sleepTime ); Thread.sleep( sleepTime ); /线程休眠 catch ( InterruptedException exception ) ; System.out.println( getName() + finished 8.1.2 Thread类类(续续)例例8_2多线程编程基础15l运行结果运行结果Starting threadsThreads started, main endsthread1 going to sleep for 3519thread2 going to sleep for 1689thread3 going to sleep for 5565thread2 finishedthread1 finishedthread3 finishedl说明说明由于线程3休眠时间最长,所以最后结束,线程2休眠时间最短,所以最先结束每次运行,都会产生不同的随机休眠时间,所以结果都不相同8.1.2 Thread类类(续续)例例8_2运行结果运行结果多线程编程基础168.1.3 Runnable接口接口lRunnable接口接口Java多线程机制的一个重要部分,实际上它只有一个run()方法Thread类实现了Runnable接口,相对于Thread类,它更适合于多个线程处理同一资源实现Runnable接口的类的对象可以用来创建线程,这时start方法启动此线程就会在此线程上运行run()方法在编写复杂程序时相关的类可能已经继承了某个基类,而Java不支持多继承,在这种情况下,便需要通过实现Runnable接口来生成多线程多线程编程基础17l使用使用Runnable接口实现例接口实现例8_1功能功能public class Ex8_1 public static void main( String args ) System.out.println(main thread starts); FactorialThread t=new FactorialThread(10); new Thread(t).start(); System.out.println(new thread started,main thread ends ); 8.1.3 Runnable接口接口(续续)例例8_3多线程编程基础18class FactorialThread implements Runnable private int num; public FactorialThread( int num ) this.num=num; public void run() int i=num; int result=1; while(i0) result=result*i; i=i-1; System.out.println(The factorial of +num+ is +result); System.out.p