《《移动通信软件编程基础—JAVA语言》第11章.ppt》由会员分享,可在线阅读,更多相关《《移动通信软件编程基础—JAVA语言》第11章.ppt(36页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、知识回顾知识回顾I/OI/O输入输入 与输出与输出 基本文件操作基本文件操作字节流字节流字符流字符流FileFile类类使用流使用流FileInputStreamFileInputStream类和类和FileOutputStreamFileOutputStream类类控制台输入流控制台输入流System.inSystem.in过滤流过滤流缓冲流缓冲流包装流包装流字节流和字符流的比较字节流和字符流的比较FileReaderFileReader类与类与BufferedReaderBufferedReader类类FileWriterFileWriter类与类与BufferedReaderBuffer
2、edReader类类11多线程第章本章目标本章目标线程的基本概念线程的基本概念JavaJava中线程的实现方法中线程的实现方法线程的优先级线程的优先级J Javaava中同步的实现中同步的实现 死锁及其解决方法死锁及其解决方法进程的基本概念进程的基本概念 进程进程1 1 进程进程2 2进程间的关系比较疏远;进程间的关系比较疏远;各个进程是在自己独有的地址空间内执行各个进程是在自己独有的地址空间内执行。线程的基本概念线程的基本概念 进程进程存储器存储器线程线程1 1线程线程2 2线程的基本概念线程的基本概念v线程是进行中的实体,一个进程中可以包含一个或多线程是进行中的实体,一个进程中可以包含一个
3、或多个线程。个线程。v一个线程在执行期间同样有一个开始,一个执行序列一个线程在执行期间同样有一个开始,一个执行序列和一个结束点。和一个结束点。v单个线程不是一个程序,并不能依靠自身单独执行,单个线程不是一个程序,并不能依靠自身单独执行,它必须在程序中执行。它必须在程序中执行。v基于线程的多任务处理环境中,线程是最小的处理单基于线程的多任务处理环境中,线程是最小的处理单位。实现多任务需要多线程。位。实现多任务需要多线程。线程的基本概念线程的基本概念多线程:多线程:v在在JavaJava中,一个应用程序可以包含多个线程。每个中,一个应用程序可以包含多个线程。每个线程执行特定的任务,并可与其他线程并
4、发执行。线程执行特定的任务,并可与其他线程并发执行。v多线程使系统的空转时间减少,提高多线程使系统的空转时间减少,提高CPUCPU利用率。利用率。v多线程编程环境用方便的模型隐藏多线程编程环境用方便的模型隐藏CPUCPU在任务间切换在任务间切换的事实。的事实。主线程主线程public class MainThreadDemo public static void main(String args)/获得主线程的一个引用获得主线程的一个引用 Thread t=Thread.currentThread();/输出线程信息输出线程信息 System.out.println(t);运行运行结果结果输出
5、默认的线程信息输出默认的线程信息Threadmain,5,mainThreadmain,5,mainThread类的常用方法类的常用方法方法方法说明说明void run()运行一个线程运行一个线程void start()启动线程并调用启动线程并调用run方法方法static currentThread()返回当前执行的线程返回当前执行的线程void join()等待线程终止等待线程终止final void setName(String name)改变线程的内部名称改变线程的内部名称final String getName()返回线程的内部名称返回线程的内部名称static void sleep
6、(long millis)设置线程为休眠状态设置线程为休眠状态Thread类常用方法的使用public class CreateThreadDemopublic static void main(String args)Thread T=Thread.currentThread();System.out.println(T);T.setName(ThreadNew);System.out.println(T);for(int i=0;i10;i+)System.out.println(i);try T.sleep(1000);catch(InterruptedException ie)ie.p
7、rintStackTrace();创建一个线程类创建一个线程类class MyThread extends Thread public MyThread(String name)super(name);public void run()for(int i=0;i10;i+)System.out.println(实现线程实现线程:+this);try sleep(1000);catch(InterruptedException ie)ie.printStackTrace();public class CreateThreadDemo public static void main(String
8、args)MyThread T=new MyThread(study);T.start();线程的状态线程的状态v线程的状态:新生、就绪、运行、睡眠、挂起、阻塞、线程的状态:新生、就绪、运行、睡眠、挂起、阻塞、死亡七种状态,线程从新生到死亡的状态变化过程称为生死亡七种状态,线程从新生到死亡的状态变化过程称为生命周期命周期 线程状态的实现线程状态的实现新建新建建立了一个线程对象线程处于新建状态建立了一个线程对象线程处于新建状态就绪就绪在创建线程后,它将处于就绪状态在创建线程后,它将处于就绪状态运行运行线程在开始执行时进入运行状态线程在开始执行时进入运行状态睡眠睡眠线程的执行可通过使用线程的执行可
9、通过使用sleep()sleep()方法来暂时中止方法来暂时中止等待等待如果调用了如果调用了wait()wait()方法,线程将处于等待状态方法,线程将处于等待状态挂起挂起suspend()suspend()方法使用线程处于挂起状态方法使用线程处于挂起状态恢复恢复resume()resume()方法可以使用挂起的线程方法可以使用挂起的线程阻塞阻塞在线程等待一个事件时(例如输入在线程等待一个事件时(例如输入/输出操作),输出操作),就称其处于阻塞状态就称其处于阻塞状态死亡死亡在在run()run()方法已完成执行或其方法已完成执行或其stop()stop()方法被调用之方法被调用之后,线程就处于
10、死亡状态后,线程就处于死亡状态线程状态的实现线程状态的实现class MyThread extends Thread public MyThread(String name)super(name);System.out.println(线程就绪线程就绪);public void start()System.out.println(线程启动线程启动);run();public void run()System.out.println(线程运行线程运行);try System.out.println(线程将要休眠线程将要休眠10秒秒);sleep(1000);System.out.println(
11、线程休眠线程休眠10秒继续运行秒继续运行);catch(InterruptedException ie)ie.printStackTrace();public class CreateThreadDemo public static void main(String args)MyThread T=new MyThread(study);T.start();System.out.println(线程死亡线程死亡);暂停线程的方法暂停线程的方法线程让出线程让出CPU时间片的方法:时间片的方法:无法获得无法获得CPU时间:线程优先级比较低时间:线程优先级比较低线程休眠:使用线程休眠:使用sleep
12、()方法方法线程显式出让线程显式出让CPU控制权:调用控制权:调用yield()方法方法线程等待:调用线程等待:调用wait()方法方法阻塞:线程由于等待一个文件阻塞:线程由于等待一个文件I/O事件事件线程优先级线程优先级class ChildThread extends Threadpublic void run()while(true)System.out.println(this+子线程在运行子线程在运行);yield();public class ThreadPriorityDemopublic static void main(String args)Thread MainT=Thr
13、ead.currentThread();ChildThread ChildT=new ChildThread();ChildT.setPriority(Thread.MAX_PRIORITY);ChildT.start();for(int i=0;i 0)try Thread.sleep(5);catch(InterruptedException ie)ie.printStackTrace();System.out.println(Thread.currentThread().getName()+销售票号为销售票号为:+tickets-);public class TicketsSalepub
14、lic static void main(String args)ThreadSale T=new ThreadSale();Thread T1=new Thread(T);Thread T2=new Thread(T);Thread T3=new Thread(T);Thread T4=new Thread(T);T1.start();T2.start();T3.start();T4.start();使用使用Runnable接口实现多窗口售票接口实现多窗口售票线程同步线程同步v程序中不能有多个线程同时在两句代码之间执行,程序中不能有多个线程同时在两句代码之间执行,这就是线程同步。这就是线程同
15、步。v为了确保在任何时间点一个共享的资源只能被一个为了确保在任何时间点一个共享的资源只能被一个线程使用,就需要使用线程使用,就需要使用“同步同步”。v实现同步的方法有两种:实现同步的方法有两种:同步代码块同步代码块同步方法同步方法同步代码块同步代码块v同步代码块模式如下所示,其中同步代码块模式如下所示,其中Object可以是任意可以是任意的一个对象。的一个对象。synchronized(object)/要同步的语句要同步的语句 使用此方法解决售票系统的问题使用此方法解决售票系统的问题 class ThreadSale implements Runnable private int ticket
16、s=100;Object obj=new Object();/同步块对象同步块对象,任意对象均可任意对象均可 public void run()synchronized(obj)if(tickets 0)System.out.println(Thread.currentThread().getName()+销售票号为销售票号为:+tickets-);死锁死锁v当两个线程循环依赖于一对同步对象时将发生死锁当两个线程循环依赖于一对同步对象时将发生死锁v死锁是很难调试的错误死锁是很难调试的错误死锁的解决方法死锁的解决方法vwait-notifywait-notify机制是解决由于使用机制是解决由于使
17、用synchronizedsynchronized方方法或块产生的死锁问题,实现线程间的通信。法或块产生的死锁问题,实现线程间的通信。vwaitwait方法:线程对象在调用方法:线程对象在调用sleep()sleep()后并不释放对后并不释放对象的锁,调用象的锁,调用wait()wait()的时候会释放对象的锁。的时候会释放对象的锁。vnotifynotify方法:唤醒同一对象监视器中调用方法:唤醒同一对象监视器中调用waitwait的第的第一个线程。被通知的线程重新获得监视器的锁定继一个线程。被通知的线程重新获得监视器的锁定继续运行。续运行。vnotifyAllnotifyAll方法:唤醒同
18、一对象监视器中调用方法:唤醒同一对象监视器中调用waitwait的所有线程,具有最高优先级的线程首先被唤醒并的所有线程,具有最高优先级的线程首先被唤醒并执行。执行。wait-notify机制示例class ThreadB extends Thread int total=0;public void run()synchronized(this)for(int i=0;i=100;i+)total+=i;System.out.println(计算完成计算完成.);notify();public void synModify()public void synModify()synchronized
19、(this)try System.out.println(在此等待直到计算完成在此等待直到计算完成.);wait();System.out.println(返回继续执行返回继续执行!);catch(InterruptedException e)e.printStackTrace();System.out.println(显示结果显示结果:+total);wait-notify机制示例 public class WaitNotifyDemo public static void main(String args)ThreadB b=new ThreadB();b.start();b.synMod
20、ify();生产者/消费者问题/生产者线程类生产者线程类class Producer extends Thread private CubbyHole cubbyhole;private int number;public Producer(CubbyHole c,int number)cubbyhole=c;this.number=number;public void run()public void run()for(int i=0;i 10;i+)int temp=(int)(Math.random()*1000);cubbyhole.put(temp);System.out.print
21、ln(Producer#+this.number +put:+temp);try sleep(int)(Math.random()*1000);catch e.printStackTrace();生产者/消费者问题/消费者线程类消费者线程类 class Consumer extends Thread private CubbyHole cubbyhole;private int number;public Consumer(CubbyHole c,int number)cubbyhole=c;this.number=number;public void run()int value=0;for
22、(int i=0;i 10;i+)value=cubbyhole.get();System.out.println(Consumer#+this.number +get:+value);生产者/消费者问题/共享数据类共享数据类-模拟实现仓库模拟实现仓库class CubbyHole private int seq;private boolean available=false;/取数据的同步方法取数据的同步方法get()-取得可消费产品取得可消费产品 public synchronized int get()/存放数据的同步方法存放数据的同步方法put()-放置可消费产品放置可消费产品 pub
23、lic synchronized void put(int value)public synchronized int get()while(available=false)try wait();/条件不符合,则条件不符合,则wait catch(InterruptedException e)e.printStackTrace();available=false;/修改条件修改条件-取得产品后取得产品后 notify();/通知唤醒其他等待的线程通知唤醒其他等待的线程 return seq;/返回要取出的数值返回要取出的数值 public synchronized void put(int v
24、alue)while(available=true)try wait();/条件不符合,则条件不符合,则wait catch(InterruptedException e)e.printStackTrace();seq=value;/把共享变量修改为要放置的数据把共享变量修改为要放置的数据 available=true;/修改条件修改条件 notify();/通知唤醒其他等待管程的线程通知唤醒其他等待管程的线程生产者/消费者问题 public class ProductConsumerDemo public static void main(String args)CubbyHole c=ne
25、w CubbyHole();/共享数据对象共享数据对象 Producer p1=new Producer(c,1);/生产者线程生产者线程 Consumer c1=new Consumer(c,5);/消费者线程消费者线程 p1.start();/启动生产者线程启动生产者线程 p2.start();/启动生产者线程启动生产者线程 c1.start();/启动消费者线程启动消费者线程 c2.start();/启动消费者线程启动消费者线程 v生产消费者主程序生产消费者主程序总结总结 多线程多线程 线程的基本概念线程的基本概念线程的实现方法线程的实现方法同步的实现同步的实现死锁及其解决方案死锁及其解决方案线程的基本概念线程的基本概念创建线程创建线程线程的状态线程的状态暂停线程的方法暂停线程的方法线程的优先级线程的优先级继承继承Thread类类实现实现Runnable接口接口同步方法同步方法同步代码块同步代码块死锁死锁wait-notify机制机制习题习题作业作业