java程序设计第8章.ppt

上传人:小飞机 文档编号:6510025 上传时间:2023-11-07 格式:PPT 页数:74 大小:234KB
返回 下载 相关 举报
java程序设计第8章.ppt_第1页
第1页 / 共74页
java程序设计第8章.ppt_第2页
第2页 / 共74页
java程序设计第8章.ppt_第3页
第3页 / 共74页
java程序设计第8章.ppt_第4页
第4页 / 共74页
java程序设计第8章.ppt_第5页
第5页 / 共74页
点击查看更多>>
资源描述

《java程序设计第8章.ppt》由会员分享,可在线阅读,更多相关《java程序设计第8章.ppt(74页珍藏版)》请在三一办公上搜索。

1、第八章 线程,JAVA语言程序设计,2,目录,多线程编程基础线程的生命周期线程的优先级本章小结,3,8.1 多线程编程基础,本节内容线程的概念Thread类Runnable接口线程间的数据共享多线程的同步控制线程之间的通信后台线程,4,8.1.1 线程的概念,进程和线程的区别进程一个独立程序的每一次运行称为一个进程,例如用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程设置一个进程要占用相当一部分处理器时间和内存资源大多数操作系统不允许进程访问其他进程的内存空间,进程间的通信很不方便,编程模型比较复杂,多线程编程基础,5,线程一个程序中多段代码同时并

2、发执行,称为多线程通过多线程,一个进程表面上看同时可以执行一个以上的任务并发创建线程比创建进程开销要小得多,线程之间的协作和数据交换也比较容易Java是第一个支持内置线程操作的主流编程语言多数程序设计语言支持多线程要借助于操作系统“原语(primitives)”,8.1.1 线程的概念(续),多线程编程基础,6,8.1.2 Thread类,Thread类在Java程序中创建多线程的方法之一是继承Thread类 封装了Java程序中一个线程对象需要拥有的属性和方法从Thread类派生一个子类,并创建这个子类的对象,就可以产生一个新的线程。这个子类应该重写Thread类的run方法,在run方法中

3、写入需要在新线程中执行的语句段。这个子类的对象需要调用start方法来启动,新线程将自动进入run方法。原线程将同时继续往下执行Thread类直接继承了Object类,并实现了Runnable接口。它位于java.lang包中,因而程序开头不用import任何包就可直接使用,多线程编程基础,7,8.1.2 Thread类(续)例8_1,在新线程中完成计算某个整数的阶乘public class Ex8_1 public static void main(String args)System.out.println(main thread starts);FactorialThread threa

4、d=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;,多线程编程基础,8,public void run()int i=num;int result=1;System.out.println(new thread started);while(i0)result=result*i;i=i-1;Syst

5、em.out.println(The factorial of+num+is+result);System.out.println(new thread ends);运行结果main thread startsmain thread endsnew thread startedThe factorial of 10 is 3628800new thread ends,8.1.2 Thread类(续)例8_1运行结果,多线程编程基础,9,结果说明main线程已经执行完后,新线程才执行完main函数调用thread.start()方法启动新线程后并不等待其run方法返回就继续运行,thread.r

6、un函数在一边独自运行,不影响原来的main函数的运行源程序修改如果启动新线程后希望主线程多持续一会再结束,可在start语句后加上让当前线程(这里当然是main)休息1毫秒的语句:try Thread.sleep(1);catch(Exception e);,8.1.2 Thread类(续)例8_1修改,多线程编程基础,10,修改后运行结果main thread startsnew thread staredThe factorial of 10 is 3628800new thread endsmain thread ends运行结果说明新线程结束后main线程才结束,8.1.2 Thre

7、ad类(续)例8_1修改后运行结果,多线程编程基础,11,8.1.2 Thread类(续)常用API函数,多线程编程基础,12,8.1.2 Thread类(续)常用API函数,多线程编程基础,13,8.1.2 Thread类(续)常用API函数,多线程编程基础,14,创建3个新线程,每个线程睡眠一段时间(06秒),然后结束public class Ex8_2 public static void main(String args)/创建并命名每个线程 TestThread thread1=new TestThread(thread1);TestThread thread2=new TestTh

8、read(thread2);TestThread thread3=new TestThread(thread3);(Starting threads);thread1.start();/启动线程1 thread2.start();/启动线程2 thread3.start();/启动线程3(Threads started,main endsn);,8.1.2 Thread类(续)例8_2,多线程编程基础,15,class TestThread extends Thread private int sleepTime;public TestThread(String name)super(name

9、);sleepTime=(int)(Math.random()*6000);public void run()try(getName()+going to sleep for+sleepTime);Thread.sleep(sleepTime);/线程休眠 catch(InterruptedException exception);(getName()+finished,8.1.2 Thread类(续)例8_2,多线程编程基础,16,运行结果Starting threadsThreads started,main endsthread1 going to sleep for 3519threa

10、d2 going to sleep for 1689thread3 going to sleep for 5565thread2 finishedthread1 finishedthread3 finished说明由于线程3休眠时间最长,所以最后结束,线程2休眠时间最短,所以最先结束每次运行,都会产生不同的随机休眠时间,所以结果都不相同,8.1.2 Thread类(续)例8_2运行结果,多线程编程基础,17,8.1.3 Runnable接口,Runnable接口Java多线程机制的一个重要部分,实际上它只有一个run()方法Thread类实现了Runnable接口,相对于Thread类,它更适

11、合于多个线程处理同一资源实现Runnable接口的类的对象可以用来创建线程,这时start方法启动此线程就会在此线程上运行run()方法在编写复杂程序时相关的类可能已经继承了某个基类,而Java不支持多继承,在这种情况下,便需要通过实现Runnable接口来生成多线程,多线程编程基础,18,使用Runnable接口实现例8_1功能public class Ex8_1 public static void main(String args)System.out.println(main thread starts);FactorialThread t=new FactorialThread(10

12、);new Thread(t).start();System.out.println(new thread started,main thread ends);,8.1.3 Runnable接口(续)例8_3,多线程编程基础,19,class 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.

13、println(The factorial of+num+is+result);System.out.println(new thread ends);,8.1.3 Runnable接口(续)例8_3,多线程编程基础,20,使用Runnable接口实现例8_2功能public class Ex8_4 public static void main(String args)TestThread thread1=new TestThread();TestThread thread2=new TestThread();TestThread thread3=new TestThread();(Star

14、ting threads);new Thread(thread1,Thread1).start();new Thread(thread2,Thread2).start();new Thread(thread3,Thread3).start();(Threads started,main endsn);,8.1.3 Runnable接口(续)例8_4,多线程编程基础,21,class TestThread implements Runnable private int sleepTime;public TestThread()sleepTime=(int)(Math.random()*6000)

15、;public void run()try(Thread.currentThread().getName()+going to sleep for+sleepTime);Thread.sleep(sleepTime);catch(InterruptedException exception);(Thread.currentThread().getName()+finished);,8.1.3 Runnable接口(续)例8_4,多线程编程基础,22,8.1.4 线程间的数据共享,代码共享多个线程的执行代码来自同一个类的run方法时,即称它们共享相同的代码数据共享当共享访问相同的对象时,即它们共

16、享相同的数据使用Runnable接口可以轻松实现多个线程共享相同数据,只要用同一个实现了Runnable接口的实例作为参数创建多个线程就可以了,多线程编程基础,23,修改例8_4,只用一个Runnable类型的对象为参数创建3个新线程。public class Ex8_5 public static void main(String args)TestThread threadobj=new TestThread();(Starting threads);new Thread(threadobj,Thread1).start();new Thread(threadobj,Thread2).st

17、art();new Thread(threadobj,Thread3).start();(Threads started,main endsn);,8.1.4 线程间的数据共享(续)例8_5,多线程编程基础,24,class TestThread implements Runnable private int sleepTime;public TestThread()sleepTime=(int)(Math.random()*6000);public void run()try(Thread.currentThread().getName()+going to sleep for+sleepT

18、ime);Thread.sleep(sleepTime);catch(InterruptedException exception);(Thread.currentThread().getName()+finished);,8.1.4 线程间的数据共享(续)例8_5,多线程编程基础,25,运行结果Starting threadsThread1 going to sleep for 966Thread2 going to sleep for 966Threads started,main endsThread3 going to sleep for 966Thread1 finishedThre

19、ad2 finishedThread3 finished说明因为是用一个Runnable类型对象创建的3个新线程,这三个线程就共享了这个对象的私有成员sleepTime,在本次运行中,三个线程都休眠了966毫秒,8.1.4 线程间的数据共享(续)例8_5运行结果,多线程编程基础,26,8.1.4 线程间的资源共享(续),独立的同时运行的线程有时需要共享一些数据并且考虑到彼此的状态和动作例如生产/消费问题:生产线程产生数据流,然后这些数据流再被消费线程消费假设一个Java应用程序,其中有一个线程负责往文件写数据,另一个线程从同一个文件中往出都数据,因为涉及到同一个资源,这里是同一个文件,这两个线

20、程必须保证某种方式的同步,多线程编程基础,27,用三个线程模拟三个售票口,总共出售200张票用3个线程模仿3个售票口的售票行为这3个线程应该共享200张票的数据public class Ex8_6public static void main(String args)SellTickets t=new SellTickets();new Thread(t).start();new Thread(t).start();new Thread(t).start();,多线程编程基础,8.1.4 线程间的数据共享(续)例8_6,28,class SellTickets implements Runna

21、bleprivate int tickets=200;public void run()while(tickets0)(Thread.currentThread().getName()+is selling ticket+tickets-);,8.1.4 线程间的数据共享(续)例8_6,多线程编程基础,29,运行结果选最后几行如下Thread-2 is selling ticket 6Thread-1 is selling ticket 5Thread-0 is selling ticket 4Thread-2 is selling ticket 3Thread-1 is selling ti

22、cket 2Thread-0 is selling ticket 1说明在这个例子中,创建了3个线程,每个线程调用的是同一个SellTickets对象中的run()方法,访问的是同一个对象中的变量(tickets)如果是通过创建Thread类的子类来模拟售票过程,再创建3个新线程,则每个线程都会有各自的方法和变量,虽然方法是相同的,但变量却是各有200张票,因而结果将会是各卖出200张票,和原意就不符了,8.1.4 线程间的数据共享(续)例8_6运行结果,多线程编程基础,30,8.1.5 多线程的同步控制,有时线程之间彼此不独立、需要同步线程间的互斥同时运行的几个线程需要共享一个(些)数据一个

23、线程对共享的数据进行操作时,不允许其他线程打断它,否则会破坏数据的完整性。即被多个线程共享的数据,在某一时刻只允许一个线程对其进行操作“生产者/消费者”问题生产者产生数据,消费者消费数据,具体来说,假设有一个Java应用程序,其中有一个线程负责往数据区写数据,另一个线程从同一数据区中读数据,两个线程可以并行执行(类似于流水线上的两道工序)如果数据区已满,生产者要等消费者取走一些数据后才能再放;而当数据区没有数据时,消费者要等生产者放入一些数据后再取,多线程编程基础,31,用两个线程模拟存票、售票过程 假定开始售票处并没有票,一个线程往里存票,另外一个线程则往出卖票我们新建一个票类对象,让存票和

24、售票线程都访问它。本例采用两个线程共享同一个数据对象来实现对同一份数据的操作public class Ex8_7 public static void main(String args)Tickets t=new Tickets(10);new Consumer(t).start();new Producer(t).start();,8.1.5 多线程的同步控制(续)例8_7,多线程编程基础,32,class Tickets int number=0;/票号int size;/总票数boolean available=false;/表示目前是否有票可售public Tickets(int si

25、ze)/构造函数,传入总票数参数this.size=size;,8.1.5 多线程的同步控制(续)例8_7,多线程编程基础,33,class Producer extends ThreadTickets t=null;public Producer(Tickets t)this.t=t;public void run()while(t.number t.size)System.out.println(Producer puts ticket+(+t.number);t.available=true;,8.1.5 多线程的同步控制(续)例8_7,多线程编程基础,34,class Consumer

26、 extends Thread/售票线程Tickets t=null;int i=0;public Consumer(Tickets t)this.t=t;public void run()while(it.size)if(t.available=true,8.1.5 多线程的同步控制(续)例8_7,多线程编程基础,35,运行结果Producer puts ticket 1Producer puts ticket 2Producer puts ticket 3Producer puts ticket 4Producer puts ticket 5Producer puts ticket 6Pr

27、oducer puts ticket 7Producer puts ticket 8Consumer buys ticket 1Consumer buys ticket 2Consumer buys ticket 3Consumer buys ticket 4Consumer buys ticket 5Consumer buys ticket 6Consumer buys ticket 7Consumer buys ticket 8Producer puts ticket 9Producer puts ticket 10Consumer buys ticket 9Consumer buys t

28、icket 10.通过让两个线程操纵同一个票类对象,实现了数据共享的目的,8.1.5 多线程的同步控制(续)例8_7运行结果,多线程编程基础,36,设想一下,假如售票线程运行到t.available=false之前,CPU切换到存票线程,存票线程将available置为true,并直到整个存票线程结束。再次切换到售票线程后,售票线程执行t.available=false。此时售票号小于存票数,且存票线程已经结束不再能将t.available置为true,则售票线程陷入了死循环如果我们在t.available=false之前加上sleep语句,让售票线程多停留一会,则可以更加清楚地看到这个问题i

29、f(i=t.number)try Thread.sleep(1);catch(InterruptedException exception);t.available=false;,8.1.5 多线程的同步控制(续)例8_7修改,多线程编程基础,37,修改后运行结果Producer puts ticket 1Producer puts ticket 2Producer puts ticket 3Producer puts ticket 4Producer puts ticket 5Producer puts ticket 6Producer puts ticket 7Producer puts

30、ticket 8Consumer buys ticket 1Consumer buys ticket 2Consumer buys ticket 3Consumer buys ticket 4Consumer buys ticket 5Consumer buys ticket 6Consumer buys ticket 7Consumer buys ticket 8Producer puts ticket 9Producer puts ticket 10,8.1.5 多线程的同步控制(续)例8_7修改后运行结果,多线程编程基础,38,如何避免上面这种意外,让我们的程序是“线程安全”的呢?解决线

31、程的同步/互斥问题存票线程和售票线程应保持互斥关系。即售票线程执行时不进入存票线程、存票线程执行时不进入售票线程Java 使用的同步机制是监视器每个对象都只有一个“锁旗标”与之相连,利用多线程对其的争夺可实现线程间的互斥操作当线程A获得了一个对象的锁旗标后,线程B必须等待线程A完成规定的操作、并释放出锁旗标后,才能获得该对象的锁旗标,并执行线程B中的操作,8.1.5 多线程的同步控制(续)解决例8_7的问题,多线程编程基础,39,线程同步的概念,包括互斥和协作互斥:许多线程在同一个共享数据上操作而互不干扰,同一时刻只能有一个线程访问该共享数据。因此有些方法或程序段在同一时刻只能被一个线程执行,

32、称之为监视区协作:多个线程可以有条件地同时操作共享数据。执行监视区代码的线程在条件满足的情况下可以允许其它线程进入监视区,8.1.5 多线程的同步控制(续)线程同步(Synchronization),多线程编程基础,40,synchronized 线程同步关键字用于指定需要同步的代码段或方法,也就是监视区可实现与一个锁旗标的交互。例如:synchronized(对象)代码段 synchronized的功能是:首先判断对象的锁旗标是否在,如果在就获得锁旗标,然后就可以执行紧随其后的代码段;如果对象的锁旗标不在(已被其他线程拿走),就进入等待状态,直到获得锁旗标当被synchronized限定的代

33、码段执行完,就释放锁旗标,8.1.5 多线程的同步控制(续)synchronized关键字,多线程编程基础,41,将需要互斥的语句段放入synchronized(object)语句框中,且两处的object是相同的class Producer extends Thread Tickets t=null;public Producer(Tickets t)this.t=t;public void run()while(t.number)t.size)synchronized(t)/申请对象t的锁旗标 System.out.println(Producer puts ticket+(+t.numb

34、er);t.available=true;/释放对象t的锁旗标System.out.println(Producer ends!);,8.1.5 多线程的同步控制(续)synchronized关键字,多线程编程基础,42,class Consumer extends Thread Tickets t=null;int i=0;public Consumer(Tickets t)this.t=t;public void run()while(it.size)synchronized(t)/申请对象t的锁旗标 if(t.available=true,8.1.5 多线程的同步控制(续)synchro

35、nized关键字,多线程编程基础,43,说明存票程序段和售票程序段为获得同一对象的锁旗标而实现互斥操作当线程执行到synchronized的时候,检查传入的实参对象,并申请得到该对象的锁旗标。如果得不到,那么线程就被放到一个与该对象锁旗标相对应的等待线程池中。直到该对象的锁旗标被归还,池中的等待线程才能重新去获得锁旗标,然后继续执行下去除了可以对指定的代码段进行同步控制之外,还可以定义整个方法在同步控制下执行,只要在方法定义前加上synchronized关键字即可,8.1.5 多线程的同步控制(续)synchronized关键字,多线程编程基础,44,实现例8_7功能。将互斥方法放在共享的资源

36、类Tickets中class Tickets int size;/票总数int number=0;/存票序号int i=0;/售票序号boolean available=false;/是否有待售的票public Tickets(int size)this.size=size;public synchronized void put()/同步方法,实现存票的功能 System.out.println(Producer puts ticket+(+number);available=true;public synchronized void sell()/同步方法,实现售票的功能 if(avail

37、able=true,8.1.5 多线程的同步控制(续)例8_8,多线程编程基础,45,说明同步方法使用的锁旗标关联对象正是方法所属的实例对象。在例8_8中,正是因为put和sell两个同步方法都属于同一个Tickets类的对象,所以实现了同步由于要实现多线程的数据共享,即多个线程对同一数据资源进行操作,就可能造成一个线程对资源进行了部分处理,另一个线程就插进来对其进行处理,这样就会破坏共享数据的完整性。因此,需要使用线程同步与互斥技术,防止不同的线程同时对共享数据进行修改操作。数据共享和线程互斥操作经常是密不可分的,8.1.5 多线程的同步控制(续)例8_8说明,多线程编程基础,46,8.1.

38、6 线程之间的通信,为了更有效地协调不同线程的工作,需要在线程间建立沟通渠道,通过线程间的“对话”来解决线程间的同步问题 类的一些方法为线程间的通讯提供了有效手段wait()如果当前状态不适合本线程执行,正在执行同步代码(synchronized)的某个线程A调用该方法(在对象x上),该线程暂停执行而进入对象x的等待池,并释放已获得的对象x的锁旗标。线程A要一直等到其他线程在对象x上调用notify或notifyAll方法,才能够在重新获得对象x的锁旗标后继续执行(从wait语句后继续执行),多线程编程基础,47,8.1.6 线程之间的通信(续)notify()和notifyAll()方法,n

39、otify()随机唤醒一个等待的线程,本线程继续执行线程被唤醒以后,还要等发出唤醒消息者释放监视器,这期间关键数据仍可能被改变被唤醒的线程开始执行时,一定要判断当前状态是否适合自己运行notifyAll()唤醒所有等待的线程,本线程继续执行,多线程编程基础,48,修改例8_8,使每存入一张票,就售一张票,售出后,再存入class Tickets public synchronized void put()if(available)/如果还有存票待售,则存票线程等待 try wait();catch(Exception e)System.out.println(Producer puts tic

40、ket+(+number);available=true;notify();/存票后唤醒售票线程开始售票public synchronized void sell()if(!available)/如果没有存票,则售票线程等待 try wait();catch(Exception e)System.out.println(Consumer buys ticket+(number);available=false;notify();/售票后唤醒存票线程开始存票 if(number=size)number=size+1;/在售完最后一张票后,/设置一个结束标志,numbersize表示售票结束,8.

41、1.6 线程之间的通信(续)例8_9,多线程编程基础,49,class Producer extends Thread Tickets t=null;public Producer(Tickets t)this.t=t;public void run()while(t.numbert.size)t.put();class Consumer extends Thread Tickets t=null;public Consumer(Tickets t)this.t=t;public void run()while(t.number=t.size)t.sell();,8.1.6 线程之间的通信(续

42、)例8_9,多线程编程基础,50,运行结果Producer puts ticket 1Consumer buys ticket 1Producer puts ticket 2Consumer buys ticket 2Producer puts ticket 3Consumer buys ticket 3Producer puts ticket 4Consumer buys ticket 4Producer puts ticket 5Consumer buys ticket 5Producer puts ticket 6Consumer buys ticket 6Producer puts t

43、icket 7Consumer buys ticket 7Producer puts ticket 8Consumer buys ticket 8Producer puts ticket 9Consumer buys ticket 9Producer puts ticket 10Consumer buys ticket 10,8.1.6 线程之间的通信(续)例8_9运行结果,多线程编程基础,51,程序说明当Consumer线程售出票后,available值变为false,当Producer线程放入票后,available值变为true只有available为true时,Consumer线程才能

44、售票,否则就必须等待Producer线程放入新的票后的通知只有available为false时,Producer线程才能放票,否则必须等待Consumer线程售出票后的通知可见通过线程间的通信实现了我们的要求,8.1.6 线程之间的通信(续)例8_9说明,多线程编程基础,52,8.1.7 后台线程,后台线程也叫守护线程,通常是为了辅助其它线程而运行的线程它不妨碍程序终止一个进程中只要还有一个前台线程在运行,这个进程就不会结束;如果一个进程中的所有前台线程都已经结束,那么无论是否还有未结束的后台线程,这个进程都会结束“垃圾回收”便是一个后台线程如果对某个线程对象在启动(调用start方法)之前调

45、用了setDaemon(true)方法,这个线程就变成了后台线程,多线程编程基础,53,创建一个无限循环的后台线程,验证主线程结束后,程序即结束public class Ex8_10 public static void main(String args)ThreadTest t=new ThreadTest();t.setDaemon(true);t.start();class ThreadTest extends Thread public void run()while(true)运行程序,则发现整个程序在主线程结束时就随之中止运行了,如果注释掉t.setDaemon(true)语句,则

46、程序永远不会结束,8.1.7 后台线程(续)例8_10,多线程编程基础,54,8.2 线程的生命周期,线程的生命周期线程从产生到消亡的过程 一个线程在任何时刻都处于某种线程状态(thread state),55,8.2.1 线程的几种基本状态,线程生命周期状态图,线程的生命周期,56,诞生状态线程刚刚被创建就绪状态线程的 start 方法已被执行线程已准备好运行运行状态处理机分配给了线程,线程正在运行阻塞状态(Blocked)在线程发出输入/输出请求且必须等待其返回遇到用synchronized标记的方法而未获得其监视器暂时不能进入执行时休眠状态(Sleeping)执行sleep方法而进入休眠

47、死亡状态线程已完成或退出,8.2.1 线程的几种基本状态(续),线程的生命周期,57,8.2.2 死锁问题,死锁线程在运行过程中,其中某个步骤往往需要满足一些条件才能继续进行下去,如果这个条件不能满足,线程将在这个步骤上出现阻塞线程A可能会陷于对线程B的等待,而线程B同样陷于对线程C的等待,依次类推,整个等待链最后又可能回到线程A。如此一来便陷入一个彼此等待的轮回中,任何线程都动弹不得,此即所谓死锁(deadlock)对于死锁问题,关键不在于出现问题后调试,而是在于预防,线程的生命周期,58,设想一个游戏,规则为3个人站在三角形的三个顶点的位置上,三个边上放着三个球,如图所示。每个人都必须先拿

48、到自己左手边的球,才能再拿到右手边的球,两手都有球之后,才能够把两个球都放下,Player_0,Player_1,Player_2,0,2,1,8.2.2 死锁问题(续)例8_11,线程的生命周期,59,例8_11 创建3个线程模拟3个游戏者的行为。public class Ex8_11public static void main(String args)Balls ball=new Balls();/新建一个球类对象Player0 p0=new Player0(ball);/创建0号游戏者Player1 p1=new Player1(ball);/创建1号游戏者Player2 p2=new

49、 Player2(ball);/创建2号游戏者p0.start();/启动0号游戏者p1.start();/启动1号游戏者p2.start();/启动2号游戏者class Balls/球类boolean flag0=false;/0号球的标志变量,true表示已被人拿,false表示未被任何人拿boolean flag1=false;/1号球的标志变量boolean flag2=false;/2号球的标志变量,8.2.2 死锁问题(续)例8_11,线程的生命周期,60,class Player0 extends Thread/0号游戏者的类private Balls ball;public P

50、layer0(Balls b)this.ball=b;public void run()while(true)while(ball.flag1=true);/如果1号球已被拿走,则等待 ball.flag1=true;/拿起1号球 while(ball.flag0=true);/如果0号球已被拿走,则等待 if(ball.flag1=true/放下后休息1ms,8.2.2 死锁问题(续)例8_11,线程的生命周期,61,运行结果若干次后将陷入死锁,不再有输出信息,即任何人都不能再同时拥有两侧的球程序说明如果刚好3个人都拿到了左手边的球,都等待那右手边的球,则因为谁都不能放手,则这3个线程都将陷

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号