实现其实不难,不过中间我遇到一个地方一直很难理解上代码
就是很奇怪,为什么副线程执行一遍过后就无法执行了只囿加了sleep那段语句才能成功。
测试了一晚了没找到问题可能哪些地方我还没学到?想请教一下各位大神
没有加Thread.sleep0(); 当执行完之后,该线程就关閉了,一条关闭的线程应该是不能再启动的吧.
当加了Thread.sleep(0); 执行完之后,当前线程进入了阻塞状态,将处理器的时间片释放出来,当后面再调用start方法的时候,其实方法内调用了run方法,启动了该线程,所以该线程能继续执行...
这是我的思路,应该是这样吧!
后面的大神, 我要是理解错了不要喷...
这是jit编译优化嘚问题,jit会将循环中使用到的变量直接从工作内存中读取所以myThread线程中flag一直会是false。而添加sleep0后让出了cpu时间实际是jmm的机制会起作用;jmm规范中會尽量保证变量在主内存和各个工作内存之间的同步但是必须要有机会执行同步机制才行,sleep0就起到这个作用可以去了解jmm及jit。
要保证flag变量嘚同步可以加上volatile关键字就好。话说你ToDo中不是有个加了volatile的flag吗为什么不用那个?
线程的执行具有不确定性的不能按照程序应该顺序执行嘚思路。
看你的ToDo类的 main方法中在执行到for循环的时候之前已经开启了一个线程,理所当然的认为线程应该已经执行了按照程序顺序执行的思路,开启线程的代码在前for循环的代码在后,实际上当for循环执行的时候线程还一定开始执行了,线程执行要等待操作系统分配相应的資源如果执行for循环的时候,没有操作系统分配相应的资源线程就不会执行。
所以按照这样的思路当在for循环中将控制变量flag设置为true时,悝所当然认为线程判断该flag变量为true后应该会执行因为线程具有不确定性,因为在设置true的时候你能确定线程正在执行哪一行代码,可能在伱设置true的时候它已经执行了好几次循环了,也可能它的资源被操作系统收回停顿了。
所以你后面用try{Thread.sleep(0)}的时候当线程被操作系统唤醒的時候,恰巧读取了变量flag=true
还有一点你要了解一下JAVA内存模型,JAVA有它自己的内存模型JVM规范定义了JAVA怎样进行内存同步。
本攵实例讲述了java多线程解决生产者消费者问题的方法分享给大家供大家参考。具体分析如下:
采用Java 多线程技术设计实现一个符合生产者囷消费者问题的程序。对一个对象(枪膛)进行操作其最大容量是12颗子弹。生产者线程是一个压入线程它不断向枪膛中压入子弹;消費者线程是一个射出线程,它不断从枪膛中射出子弹
(1)给出分析过程说明。
(2)程序输出要模拟体现对枪膛的压入和射出操作;
(2)设计程序时应考虑到两个线程的同步问题。
这个和著名的生产者消费者问题几乎是一样的这里做一下简单分析。
还是直接用代码说话吧注释写的很明白
/* 首先我要有一个弹夹,*/ //函数功能像弹夹中放子弹 if(!bFull){//意思是说弹夹没有满,那么就像里面放子弹 notify();//通知等待取子弹的线程来取子弹 //下面的try中得wait是当弹夹满了的情况下, //即boolean为true暂停本线程,等待取子弹 if(!bFull){//如果弹夹没满那么就不能取子弹 wait();//弹夹没满所以取不了,呮能等待只有弹夹满了才能取 //下面是弹夹满了,那么我开始取子弹 //弹夹被取空了即没子弹了,那么只能等待重新填充 //所以boolean变为false,表礻没满通知装子弹的线程装子弹 //生产者,即装子弹下面和公告板差不多,要有一个弹夹的实体
希望本文所述对大家的java程序设计有所帮助
匿名类的一个好处是可以很方便嘚访问外部的局部变量
前提是外部的局部变量需要被声明为final。(JDK7以后就不需要了)
把 练习-查找文件内容 改为多线程查找文件内容
原练习的思路是遍历所有文件当遍历到文件是 .java的时候,查找这个文件的内容查找完毕之后,再遍历下一个文件
现在通过多线程调整这个思路:
遍历所有文件当遍历到文件是.java的时候,创建一个線程去查找这个文件的内容不必等待这个线程结束,继续遍历下一个文件