动态网站制作指南 [  QQ表情  ]
[ 投票调查 ]
[ 企业邮箱 ]
[ 网站空间 ]
网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
ASP源码 | .Net源码 | PHP源码 | JSP源码 | JAVA源码 | CGI源码 | VB源码 | C++源码 | Delphi源码 | PB源码 | VF源码 | 汇编 | 服务器
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java教程
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
文章搜索服务
邮件订阅
输入你的邮件地址,
你将不会错过任何关于:
[ Java教程 ]的信息

本月文章推荐
.用JWSDP将Java和Web服务结合起来.
.java入门文章--安装.
.Java.until.Map,Set,List的资料整.
.JAVA程序员必读:基础篇(2.b)语言.
.实例:用Java的加密机制来保护你.
.获得消息:J2EE 1.4 中的消息.
.实体对象的抽象以及一种基于数据.
.Java高级日期概念 (献给那些要国.
.Beans入门必读之无状态会话bean基.
.在 Java 应用程序中访问USB设备.
.JAVA对象转为JavaString的几种常.
.J2ME程序开发全方位基础讲解汇总.
.java常见缩略词及英文对照.
.在3D MIDlet应用程序中运用动画材.
.浅谈 Java 中 this 的使用.
.Apusic应用服务器的性能调节_JVM.
.用ApacheTorque项目来提升Java程.
.创建struts1.2 + Hibe.
.[JAVA100例]052、使用ODBC连接数.
.Web Services被列为今年IDC重点观.

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

发表日期:2008-1-5 |



我在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.1
class 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<100;i++ )
{
total +=i;
System.out.println("total is "+total);
}
notify();
}
}
}

要分析这个程序,首先要理解notify()和wait(),为什么在前几天纪录线程的时候没有纪录这两个方法呢,因为这两个方法本来就不属于Thread类,而是属于最底层的object基础类的,也就是说不光是Thread,每个对象都有notify和wait的功能,为什么?因为他们是用来操纵锁的,而每个对象都有锁,锁是每个对象的基础,既然锁是基础的,那么操纵锁的方法当然也是最基础了.

再往下看之前呢,首先最好复习一下Think in Java的14.3.1中第3部分内容:等待和通知,也就是wait()和notify了.

按照Think in Java中的解释:"wait()答应我们将线程置入“睡眠”状态,同时又“积极”地等待条件发生改变.而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒,并检查条件是否有变."

我们来解释一下这句话.
"wait()答应我们将线程置入“睡眠”状态",也就是说,wait也是让当前线程阻塞的,这一点和sleep或者suspend是相同的.那和sleep,suspend有什么区别呢?

区别在于"(wait)同时又“积极”地等待条件发生改变",这一点很要害,sleep和suspend无法做到.因为我们有时候需要通过同步(synchronized)的帮助来防止线程之间的冲突,而一旦使用同步,就要锁定对象,也就是获取对象锁,其它要使用该对象锁的线程都只能排队等着,等到同步方法或者同步块里的程序全部运行完才有机会.在同步方法和同步块中,无论sleep()还是suspend()都不可能自己被调用的时候解除锁定,他们都霸占着正在使用的对象锁不放.
而wait却可以,它可以让同步方法或者同步块暂时放弃对象锁,而将它暂时让给其它需要对象锁的人(这里应该是程序块,或线程)用,这意味着可在执行wait()期间调用线程对象中的其他同步方法!在其它情况下(sleep啊,suspend啊),这是不可能的.
但是注重我前面说的,只是暂时放弃对象锁,暂时给其它线程使用,我wait所在的线程还是要把这个对象锁收回来的呀.wait什么?就是wait别人用完了还给我啊!
好,那怎么把对象锁收回来呢?
第一种方法,限定借出去的时间.在wait()中设置参数,比如wait(1000),以毫秒为单位,就表明我只借出去1秒中,一秒钟之后,我自动收回.
第二种方法,让借出去的人通知我,他用完了,要还给我了.这时,我马上就收回来.哎,假如我设了1小时之后收回,别人只用了半小时就完了,那怎么办呢?靠!当然用完了就收回了,还管我设的是多长时间啊.

那么别人怎么通知我呢?相信大家都可以想到了,notify(),这就是最后一句话"而且只有在一个notify()或notifyAll()发生变化的时候,线程才会被唤醒"的意思了.
因此,我们可将一个wait()和notify()置入任何同步方法或同步块内部,无论在那个类里是否预备进行涉及线程的处理。而且实际上,我们也只能在同步方法或者同步块里面调用wait()和notify().

这个时候我们来解释上面的程序,简直是易如反掌了.

synchronized(b){...};的意思是定义一个同步块,使用b作为资源锁。b.wait();的意思是临时释放锁,并阻塞当前线程,好让其他使用同一把锁的线程有机会执行,在这里要用同一把锁的就是b线程本身.这个线程在执行到一定地方后用notify()通知wait的线程,锁已经用完,待notify()所在的同步块运行完之后,wait所在的线程就可以继续执行.
上一篇:菜鸟初学Java的备忘录(九) 人气:336
下一篇:查找数据表的主键 人气:431
浏览全部Java的内容 Dreamweaver插件下载 常用网页广告代码全集
  最新网站源码 最新软件下载
2008-8-28 LDV个人相册系统 v1.6.1
2008-8-28 讯时网站管理系统CMS v3.5
2008-8-28 迅易评选管理系统 v9.3
2008-8-28 OpenX(广告管理系统) v2.6.1 多国
2008-8-28 雨点单用户免费留言板 v2.0 Buil
2008-8-28 APJE私服发布系统 v2.1 ASP版
2008-8-28 酷维CMS企业网站程序 v1.0
2008-8-27 风讯dotNETCMS v1.0 SP3 SQL/ACC
2008-8-27 风讯dotNETCMS v1.0 SP3 源码
2008-8-23 Mini WinMount V0.4
2008-8-23 Vista优化大师3.11正式版
2008-8-23 Wine 1.13
2008-8-23 KlipFolio 5.0 Build 5899-80
2008-8-23 Windows Sysinternals Desktops
2008-8-23 OneTap Movies1.2破解版
2008-8-23 AnnotaterPDF阅读1.1.503 破解版
2008-8-23 SoundMeter分贝测量仪 v1.0汉化破
2008-8-23 iDrum音乐节拍1.0破解版
  发表评论
姓 名: 验证码:
内 容:
站长工具:网站收录查询 | Google PR查询 | ALEXA排名查询 | CSS在线编辑器 | 广告代码 | Html转换js | js/vbs加密 | md5加密 | 进制转换
实用工具:汉字翻译拼音 | 符号对照表 | 个税计算 | 经典小工具 | 汉字简繁转换 | 普通单位换算 | 公制单位换算 | 生辰老黄历 | 国内电话区号 国家代码与域名缩写 | 文字加密解密 | 健康查询 | 万年历 | 汉字横竖排版 | 手机号码查询 | 计算器 | ip搜索
业务联系 | 广告刊登 | 频道合作 | 投稿荐稿 | 联系方式 | 加入收藏 | RSS订阅
Copyright © 2000-2008 www.knowsky.com All rights reserved | 网络实名:动态网站制作指南 | 沪ICP备05001343号
ホームページ制作 不動産検索システム 求人情報
防水工事·改修工事 フットサル大会 探偵