第八章线程内容摘要:

票,和原意就不符了 线程间的数据共享 (续 ) —— 例 8_6运行结果 多线程编程基础 30 多线程的同步控制  有时线程之间彼此不独立、需要同步 – 线程间的互斥  同时运行的几个线程需要共享一个(些)数据  一个线程对共享的数据进行操作时,不允许其他线程打断它,否则会破坏数据的完整性。 即被多个线程共享的数据,在某一时刻只允许一个线程对其进行操作 – “生产者 /消费者” 问题  生产者产生数据,消费者消费数据,具体来说,假设有一个 Java应用程序,其中有一个线程负责往数据区写数据,另一个线程从同一数据区中读数据,两个线程可以并行执行(类似于流水线上的两道工序)  如果数据区已满,生产者要等消费者取走一些数据后才能再放;而当数据区没有数据时,消费者要等生产者放入一些数据后再取 多线程编程基础 31  用两个线程模拟存票、售票过程 – 假定开始售票处并没有票,一个线程往里存票,另外一个线程则往出卖票 – 我们新建一个票类对象,让存票和售票线程都访问它。 本例采用两个线程共享同一个数据对象来实现对同一份数据的操作 public class Ex8_7 { public static void main(String[] args) { Tickets t=new Tickets(10)。 new Consumer(t).start()。 new Producer(t).start()。 } } 多线程的同步控制 (续 ) —— 例 8_7 多线程编程基础 32 class Tickets { int number=0。 //票号 int size。 //总票数 boolean available=false。 //表示目前是否有票可售 public Tickets(int size) //构造函数,传入总票数参数 { =size。 } } 多线程的同步控制 (续 ) —— 例 8_7 多线程编程基础 33 class Producer extends Thread { Tickets t=null。 public Producer(Tickets t) { =t。 } public void run() { while( ) { (Producer puts ticket +(++))。 =true。 } } } 多线程的同步控制 (续 ) —— 例 8_7 多线程编程基础 34 class Consumer extends Thread //售票线程 { Tickets t=null。 int i=0。 public Consumer(Tickets t) { =t。 } public void run() { while(i) { if(==true amp。 amp。 i=) (Consumer buys ticket +(++i))。 if(i==) =false。 } } } 多线程的同步控制 (续 ) —— 例 8_7 多线程编程基础 35  运行结果 Producer puts ticket 1 Producer puts ticket 2 Producer puts ticket 3 Producer puts ticket 4 Producer puts ticket 5 Producer puts ticket 6 Producer puts ticket 7 Producer puts ticket 8 Consumer buys ticket 1 Consumer buys ticket 2 Consumer buys ticket 3 Consumer buys ticket 4 Consumer buys ticket 5 Consumer buys ticket 6 Consumer buys ticket 7 Consumer buys ticket 8 Producer puts ticket 9 Producer puts ticket 10 Consumer buys ticket 9 Consumer buys ticket 10.  通过让两个线程操纵同一个票类对象,实现了数据共享的目的 多线程的同步控制 (续 ) —— 例 8_7运行结果 多线程编程基础 36  设想一下,假如售票线程运行到 =false之前, CPU切换到存票线程,存票线程将 available置为 true,并直到整个存票线程结束。 再次切换到售票线程后,售票线程执行 =false。 此时售票号小于存票数,且存票线程已经结束不再能将 置为 true,则售票线程陷入了死循环  如果我们在 =false之前加上 sleep语句,让售票线程多停留一会,则可以更加清楚地看到这个问题 if(i==) { try{ (1)。 } catch ( InterruptedException exception ) {}。 =false。 } 多线程的同步控制 (续 ) —— 例 8_7修改 多线程编程基础 37  修改后运行结果 Producer puts ticket 1 Producer puts ticket 2 Producer puts ticket 3 Producer puts ticket 4 Producer puts ticket 5 Producer puts ticket 6 Producer puts ticket 7 Producer puts ticket 8 Consumer buys ticket 1 Consumer buys ticket 2 Consumer buys ticket 3 Consumer buys ticket 4 Consumer buys ticket 5 Consumer buys ticket 6 Consumer buys ticket 7 Consumer buys ticket 8 Producer puts ticket 9 Producer puts ticket 10 多线程的同步控制 (续 ) —— 例 8_7修改后运行结果 多线程编程基础 38  如何避免上面这种意外,让我们的程序是“线程安全”的呢。 – 解决线程的同步 /互斥问题 – 存票线程和售票线程应保持互斥关系。 即售票线程执行时不进入存票线程、存票线程执行时不进入售票线程  Java 使用的同步机制是监视器 – 每个对象都只有一个“锁旗标”与之相连,利用多线程对其的争夺可实现线程间的互斥操作 – 当线程 A获得了一个对象的锁旗标后,线程 B必须等待线程 A完成规定的操作、并释放出锁旗标后,才能获得该对象的锁旗标,并执行线程 B中的操作 多线程的同步控制 (续 ) —— 解决例 8_7的问题 多线程编程基础 39  线程同步的概念,包括互斥和协作 – 互斥:许多线程在同一个共享数据上操作而互不干扰,同一时刻只能有一个线程访问该共享数据。 因此有些方法或程序段在同一时刻只能被一个线程执行,称之为 监视区 – 协作:多个线程可以有条件地同时操作共享数据。 执行监视区代码的线程在条件满足的情况下可以允许其它线程进入 监视区 多线程的同步控制 (续 ) —— 线程同步 (Synchronization) 多线程编程基础 40  synchronized —— 线程同步关键字 – 用于指定需要同步的代码段或方法,也就是 监视区 – 可实现与一个锁旗标的交互。 例如:  synchronized(对象) { 代码段 } – synchronized的功能是:首先判断对象的锁旗标是否在,如果在就获得锁旗标,然后就可以执行紧随其后的代码段;如果对象的锁旗标不在(已被其他线程拿走),就进入等待状态,直到获得锁旗标 – 当被 synchronized限定的代码段执行完,就释放锁旗标 多线程的同步控制 (续 ) —— synchronized关键字 多线程编程基础 41  将需要互斥的语句段放入 synchronized(object){}语句框中,且两处的 object是相同的 class Producer extends Thread { Tickets t=null。 public Producer(Tickets t) { =t。 } public void run() { while(()) { synchronized(t) { // 申请对象 t的锁旗标 (Producer puts ticket +(++))。 =true。 } // 释放对象 t的锁旗标 } (Producer ends!)。 } } 多线程的同步控制 (续 ) —— synchronized关键字 多线程编程基础 42 class Consumer extends Thread { Tickets t=null。 int i=0。 public Consumer(Tickets t) { =t。 } public void run() { while(i) { synchronized(t) { //申请对象 t的锁旗标 if(==true amp。 amp。 i=) (Consumer buys ticket +(++i))。 if(i==) { try{(1)。 }catch(Exception e){} =false。 } } //释放对象 t的锁旗标 } (Consumer ends)。 } } 多线程的同步控制 (续 )。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。