- 1、本文档共26页,可阅读全部内容。
- 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
java程序设计教程课件-第23章java视频教程-多线程程序设计精选
* * * * * * * * * * * * * * * * * * * * * * 第23讲 多线程同步 线程并发引发的问题 线程同步原理 同步方法与同步语句块 控制线程的执行顺序-线程间交互 线程同步带来的问题-死锁与效率降低 * 线程并发引起的问题 多个线程相对执行的顺序是不确定的。 线程执行顺序的不确定性会产生执行结果的不确定性。 在多个线程对共享数据操作时常常会由于这种不确定性而产生错误。 * 线程并发引起的问题实例 一个堆栈类: public class MyStack{ private int idx = 0 ; private char[ ] data = new char[6] ; public void push( char c ){ data[idx] = c ; idx ++ ; // 栈顶指针指向下一个空单元 } public char pop( ){ idx-- ; return data[idx] ; } } * 线程并发引起的问题实例 线程a和线程b共享堆栈s 线程 a 线程b 堆栈 s 状态 时刻t1 时刻t2 时刻t3 //调用s.Push( ‘r’); data[idx]=‘r’ ; //调用s.pop( ) idx-- ; return data[idx]; //恢复运行 idx++ ; /*线程a 被抢占 idx++; 未执行*/ | p | q | | | | | idx=2 | p | q | r | | | | idx=2 | p | q | r | | | | idx=1 | p | q | r | | | | idx=2 . . . 效果:“q”被两次压栈; 线程a 压入的数据“r”丢失! * 线程并发引起的问题:实例二 public class ErrorSumThread extends Thread { public static int sumData=0; public static int times=10000; public int ID; public boolean done=false; public ErrorSumThread(int id) { ID=id; } public void run() { int d=((ID%2 ==0) ? 1:-1); System.out.println (运行线程+ID+,每次将+d+累加到sumData。); for(int i=0;itimes;i++) for(int j=0;jtimes;j++) sumData+=d; done=true; System.out.println (结束线程+ID); } * 线程并发引起的问题:实例二 public static void main(String [] args) { ErrorSumThread t1=new ErrorSumThread(1); ErrorSumThread t2=new ErrorSumThread(2); t1.start(); t2.start(); System.out.println (Integer.MAX_VALUE); while(!t1.done||!t2.done); System.out.println (sumData=+sumData); } } 如果不出问题,sumDate最后应该为0,查看实际结果 * 线程并发执行产生问题的原因 各个线程对共享数据的访问被不合理的打断。 例一中:两个线程共享一个堆栈对象,则一个线程的进栈操作语句:data[idx] = c ;idx ++不应该被另一个线程与之相关的操作打断。 例二中:两个线程共享数据sumData,则一个线程取sumData和将sumData增加一个量d的操作序列不应该被另一个线程访问sumData的操作打断。 解决办法:让线程的访问共享数据的操作序列不被打断,即让这些操作序列“串行”执行。这种方法就叫做线程同步。 * 线程同步:对象锁 对象锁:Java中每个对象(类对象和实例对象)都带有一个对象锁(monitor标志) 。对象锁是独占排它锁,即一个线程获得这个锁后,其他线程将无法再获得这个锁,直到该对象锁被释放。 * 多线程同步的原理:对象锁、等待池与同步语句块 对象锁与等待池 Java中每个对象都带有一个对象锁和一个等待池。这里的对象包括类对象和实例对象。 类对象的引用可以通过
文档评论(0)