当前位置:文档之家› java高级开发第四章(多线程)

java高级开发第四章(多线程)


ThreadDemo5
• • • • • • • • • ThreadDemo5.java public class ThreadDemo5 { public static void main(String [] args) { ThreadTest t=new ThreadTest(); new Thread(t).start(); new Thread(t).start(); new Thread(t).start();
单线程
• 在单线程中,程序代码按调用顺序依次往 下执行,在这种情况下,当主函数调用了 子函数,主函数必须等待子函数返回后才 能继续往下执行,不能实现两段程序代码 同时交替运行的效果。
单线程
• 如果要一程序中实现多段代码同时交替运 行,就需产生多个线程,并指定每个线程 上所要运行的程序代码段,这就是多线程。
用Thread类创建线程
• 将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。
• 计算大于某一规定值的质数的线程可以写 成:
用Thread类创建线程示例1
• • • • • • class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; } public void run() { // compute primes larger than minPrime . . . } • }
了解线程概念
• 一个进程中又可以包含一个或多个线程, 一个线程就是一个程序内部的一条执行线 索。
Java的线程
• JVM是一个进程,每个进程负责维护一个 主线程和其他子线程,当运行一个main函 数时可以看到系统增加了一个javaw.exe进 程。
Java线程的好处
• 之所以使用线程是因为线程可以共享内存, 因为可以共享内存所以可以把1个任务交由 多个线程并行处理,这样增加了CPU的利用 率, • 其次是因为线程的创建销毁比进程的创建 销毁开销小
• 2. 启动一个新的线程,我们不是直接调用 Thread的子类对象的run方法,而是调用 Thread子类对象的start(从Thread类中继承 的)方法,Thread类对象的start方法将产生 一个新的线程,并在该线程上运行该Thread 类对象中的run方法,根据面向对象的多态 性,在该线程上实际运行的是Thread子类 (也就是我们编写的那个类)对象中的run 方法。
单线程
• 当程序启动运行时,就自动产生了一个线 程,主函数main就是在这个线程上运行的, 当我们不再产生新的线程时,我们的程序 就是单线程的,比如我们以前的例子,它 们都是单线程的。
多线程的优势
• 多线程可以把任务分块执行,分块后可以 同时进行而不用等待。 这样效率更高如下 载文件,通过多线程就可以实现多文件下 载
• 可见,在单线程中,main函数必须等到 TestThread .run函数返回后才能继续往下执 行。而在多线程中,main函数调用 TestThread.start()方法启动了 TestThread.run()函数后,main函数不等待 TestThread.run函数返回就继续运行, TestThread.run函数在一边独自运行,不影 响原来的main函数的运行,这好比将一个 1G的CPU分成了两个500M的CPU,在一个 CPU上运行main函数,
• 而TestThread.run则在另一个CPU上运行,但 它们都在向同一个显示器上输出,所以我 们看到两个while循环处的代码同时交替运 行。 • 同样,在代码段run()中,我们也可以通过 线程的静态方法Thread.currentThread()得到 当前线程实例对象。得到当前线程对象后, 我们又调用了线程对象的getName()方法, 取出当前线程的名称字符串 。
两种实现多线程方式的对比分析
• 经过了这些曲折,这些实验,分析,我们 可以总结出,要实现这个铁路售票模拟程 序,我们只能创建一个资源对象(该对象 中包含要发售的那100 张票),但要创建多 个线程去处理这同一个资源对象,并且每 个线程上所运行的是相同的程序代码。再 回顾一下使用接口编写多线程的过程,大 家应该能够自己写出这个程序了,请大家 自己写完后,再来参看我下面给出的程序 代码。
• • • • • public class ThreadDemo2 { public static void main(String args[]) { // 调用TestThread类的start函数(从Thread 类继承而来的) • new TestThread2 ().start(); /*run()*/
ThreadDቤተ መጻሕፍቲ ባይዱmo3
• ThreadDemo3.java • public class ThreadDemo3 • { • public static void main(String args[]) • { • //new TestThread ().start(); • TestThread tt= new TestThread();//创建 TestThread类的一个实例 •
两种实现多线程方式的对比分析
• 既然直接继承Thread类和实现Runnable接口 都能实现多线程,那么这两种实现多线程 的方式在应用上有什么区别呢?我们到底 该用哪一个好呢?
两种实现多线程方式的对比分析
• 为了回答这个问题,我们通过编写一个应 用程序,来进行比较分析。我们用程序来 模拟铁路售票系统,实现通过四个售票点 发售某日某次列车的100张车票,一个售票 点用一个线程来表示。
ThreadDemo2
• 上面的代码让TestThread类继承了Thread类, 也就是TestThread类具有了Thread类的全部 特点,程序没有直接调用TestThread类对象 的run方法,而是调用了该类对象从Thread 类继承来的start方法。运行一下,我们能够 看到两个while循环处的代码同时交替运行. • 这就是我们要讲的多线程。单线程与多线 程的区别,如图所示。
• 一个代码段被执行,一定是在某个线程上 运行的,代码与线程密不可分,同一段代 码可以与多个线程相关联,在多个线程上 执行的也可以是相同的一段代码,好比多 个火车售票处按相同的操作流程(相当程 序代码)同时售票一样。
• 在上面的代码中,我们使用 Thread.currentThread()静态函数获得该代码 当前执行时对应的那个线程对象。得到当 前线程对象后,我们又调用了线程对象的 getName()方法,取出当前线程的名称字符 串。 • 代码块1处的代码能否运行呢?
创建多线程两种方法
• 继承Thread类和实现Runnable接口
用Thread类创建线程
• Java的线程是通过ng.Thread类来控制 的,一个Thread类的对象代表一个线程,而 且只能代表一个线程,通过Thread 类和它 定义的对象,我们可以获得当前线程对象、 获取某一线程的名称,可以实现控制线程 暂停一段时间等功能
两种实现多线程方式的对比分析
• • • • • • • • • 我们首先这样编写这个程序: 程序清单:ThreadDemo4.java public class ThreadDemo4 { public static void main(String [] args) { ThreadTest t=new ThreadTest(); t.start(); t.start();
两种实现多线程方式的对比分析
• 从上面运行结果上,我们发现其实只有一 个线程在运行,且抛出了异常,抛出了异 常的线程main立刻死亡!这个结果告诉我 们:一个线程对象只能启动一个线程,无 论你调用多少遍start()方法,结果都只有一 个线程。
ThreadDemo4
• 我们接着修改ThreadDemo4,在main方法中 创建四个ThreadTest对象: • public class ThreadDemo4 • { • public static void main(String [] args) • { • new ThreadTest().start(); • new ThreadTest().start(); • new ThreadTest().start();
多线程
什么是进程
• 简单地说,在多任务系统中,每个独立执 行的程序称为进程,也就是“正在进行的 程序”。
• 我们现在使用的操作系统一般都是多任务 的,即能够同时执行多个应用程序,如我 们接触最多的Windows、Linux、Unix。
• 实际情况是,操作系统负责对CPU等设备资 源进行分配和管理,虽然这些设备某一时 刻只能做一件事,但以非常小的时间间隔 交替执行多个程序,就可以给人以同时执 行多个程序的感觉。如果我们同时运行记 事本程序的两个实例,这就是两个不同的 进程。
• 屏幕上不停地打印出main is running,而不 是main thread is running,这说明代码块1处 的程序没有运行,因为代码块2先于代码块 1运行,且代码块2为无限循环,代码块1永 远没有机会运行。同时,我们也能够看到 当前线程的名称为main。
ThreadDemo2
• package test;
• 3. 由于线程的代码段在run方法中,那么该 方法执行完成以后线程也就相应的结束了, 因而我们可以通过控制run方法中的循环条 件来控制线程的终止。
使用Runnable 接口创建多线程
• 从JDK 文档中查看Runnable接口类的帮助, 该接口中只有一个run()方法,当我们使用 Thread(Runnable target)方法创建线程对象 时,需为该方法传递一个实现了Runnable 接口的类对象,这样创建的线程将调用、 那个实现了Runnable接口的类对象中的run() 方法作为其运行代码,而不再调用Thread类 中的run方法了。我们可以将上面的例子改 写成下面这样:
相关主题