您的位置:首页技术文章
文章详情页

菜鸟初学Java的备忘录(八)

【字号: 日期:2024-06-25 14:42:23浏览:7作者:猪猪
内容: 我在22号的笔记中不是有一个疑问吗?为什么我编的程序没有不同步的现象产生呢,我把它发到csdn上去了,现在我已经基本解决这个问题了,下面是论坛的回复纪录摘要回复人:bluesmile979(笑着) ( ) 信誉:100 2003-01-22 21:08:00 得分:0 说说我的看法,我认为最大的问题在于多线程,看了你的代码,好像只有两个线成了。而例子中应该是比较多的线程,多个线程竞争时间片,被打断的几率自然就大得多了。就算你加了循环,由于机器的运算速度,仍然没有多个线程竞争那么现象明显。不知道各位以为如何。回复人:xm4014(forrest) ( ) 信誉:100 2003-01-22 22:07:00 得分:0 to bluesmile979(笑着) 我也曾经想到过是否因为线程太少而导致,但是我将Think in java的例程中的两个参数都设为1来运行,那么最后也就和我写的程序一样,只有两个线程,结果照样有不同步.这又怎么解释呢回复人:tianfeichen(侧耳倾听) ( ) 信誉:110 2003-01-22 23:57:00 得分:0 线程的安排毕竟是随机的,很少会有不同步的出现,次数少了不容易发现。我常用的方法是,先让无限循环开始,循环的时候也不要求输出什么的,只加上一个停止的条件,比如:if (counter1 != counter2){ System.out.println(counter1 + ' ,' + counter2) System.exit(0);}剩下的就是等了,一般十几秒甚至几秒就出结果了,可以发现记数已经到几十万或者几百万了。如果同时开了5个线程,等了一分钟,我就算是它同步了。我的方法可能不太科学,不过效果挺好。回复人: xm4014(forrest) ( ) 信誉:100 2003-01-23 11:44:00 得分:0 可以帮我调试一下吗?为什么我按照你的方法却始终没有得到结果呢?将下面的代码直接拷贝就可以了,程序名为Sharing2.java,版本是1.4.1class TwoCounter extends Thread { private int count1 = 0, count2 = 0; private boolean started=false; public void start(){ if (!started) { started=true; super.start(); } } public void run() { while (true) { count1++; count2++;// System.out.println('Count1='+count1+',Count2='+count2); try { sleep(500); } catch (InterruptedException e){System.out.println('TwoCounter.run');} } } public void synchTest() {// Sharing2.incrementAccess(); if(count1 != count2) {System.out.println(count1+','+count2); System.exit(0); } }}class Watcher extends Thread { private Sharing2 p; public Watcher(Sharing2 p) { this.p = p; start(); } public void run() { while(true) { p.s.synchTest(); try { sleep(500); } catch (InterruptedException e){System.out.println('Watcher.run');} } }}public class Sharing2 { TwoCounter s; private static int accessCount = 0; public static void incrementAccess() {// accessCount++;// System.out.println('accessCount='+accessCount); } public static void main(String[] args) { Sharing2 aaa = new Sharing2(); aaa.s=new TwoCounter(); aaa.s.start(); new Watcher(aaa); }} ///:~另外,根据你的意思,我的程序是没有问题的,只是线程少了,不同步很难产生,要等到counter增加到很大数目的时候才有可能,对吗?回复人: hey_you(Hey) ( ) 信誉:100 2003-01-23 13:27:00 得分:0 我是这样想的:不同步而发生冲突是一种可能性,而sychronize是让这种可能性为0。你没有1发现不同步,并不能证明永远都不会发生不同步的情况,那只是一个时间问题。系统对线程的调度受了环境的影响,要是你机器上同时还跑了很多程序,可能情况就不同了。回复人: xm4014(forrest) ( ) 信誉:100 2003-01-23 15:56:00 得分:0 呵呵,我用tianfeichen(侧耳倾听)的方法运行的程序,也就是我上面贴的代码居然有结果了,counter1= 217327,counter2=217356,还真想差的不少。但是时间上绝不是一两分钟那么简单,至少过了两个小时,可能真是我和他的运行环境的不同造成的.正如hey_you(Hey)所说,只是一个时间问题.希望其它人能给出更多的看法,如果觉得没必要再讨论下去,那我就接贴.回复人: bluesmile979(笑着) ( ) 信誉:100 2003-01-23 16:38:00 得分:0 我考,一两个小时你也能坚持,服了。我认为问题结果也就两点了。一个就是我认为的线程数量另一个就是你认为的setText会有比较多的处理,占用比较多的资源。两种情况都会影响到这个问题的出现几率:)楼主宰总结一下吧,呵呵。回复人: linliangyi(蓝山咖啡) ( ) 信誉:100 2003-01-23 17:10:00 得分:0 sleep(500)占用的时间胜过for(5000)的时间,因此线程在sleep中被切换的概率远胜于在for中被中断的概率!!(回头去看我的程序就知道了)事实上,两个变量从不相等变为相等,正是说明了不同步!!顺便说一下关于swing和awt控件在线程中操作时,比如setText,常造成很多意外楼主可以看看相关的书籍!!回复人: xm4014(forrest) ( ) 信誉:100 2003-01-24 14:25:00 得分:0 我将各位的观点综合起来总结一下:首先要肯定的是,假如不使用synchronized关键字来定义同步方法或者定义同步块,那么,发生不同步的可能是绝对存在的,反过来说,synchronized就是让这种可能性为0.在第一种情况下,发生不同步的可能虽然存在,但是它的几率受到以下几个方面因素的影响1.在不同的操作系统及运行环境下,捕捉到不同步的几率可能就不一样,或者说等待的时间可能就有长有短2.程序中线程数目的多寡,如果线程太少,那么这种不同步就难于捕捉到,可能需要等待很长的时间3.代码本身的影响.比如使用awt类中涉及到GUI的方法,可能就会占用较多的资源,造成很多意外,那么发生冲突的可能性就大得多4.线程是由操作系统随机分配的,本来就存在着不确定性,这种不确定性也会影响最后的结果不知道是否正确,大家还有什么补充呢?明天正式结帖不过说实话,我有点搞不懂,为什么最后的结果,counter1(217327)和counter2(217356)会相差那么多呢.按照我的程序,即便watcher线程插到两个自加的语句中间来,检测到的这两个计数器之间的差异顶多也就是1啊.出现这么大的差异,只可能是某一个计数器的自加语句有好多次在根本没有运行的情况下就被强行中断了.这就太恐怖了!虽然有其它线程的存在会干扰当前线程,但是也不至于让当前线程语句不运行吧,最多也就是等等再运行啊?我有点糊涂了,操作系统没学好,如果大家不嫌麻烦,清帮我解释一下吧结果现在又有新的问题,我想又要等到明天才有答案吧但我们今天可以解决另一个涉及到synchronized的问题.这是我在论坛上看到的一个贴子.正是因为我解决不了,我才认为有必要回头来好好研究线程和同步等内容的.问题如下:file://分析这段程序,并解释一下,着重讲讲synchronized、wait(),notify 谢谢!class ThreadA { public static void main(String[] args) { ThreadB b=new ThreadB(); b.start(); System.out.println('b is start....'); synchronized(b)//括号里的b是什么意思,起什么作用? { try { System.out.println('Waiting for b to complete...'); b.wait();//这一句是什么意思,究竟让谁wait? System.out.println('Completed.Now back to main thread'); }catch (InterruptedException e){} } System.out.println('Total is :'+b.total); }}class ThreadB extends Thread{ int total; public void run() { synchronized(this) { System.out.println('ThreadB is running..'); for (int i=0;i
标签: Java
相关文章: