我的最新日志
-
java
2008-9-18
线程间的通信
wait:告诉当前线程放弃监视器,进入睡眠状态直到其他线程进入同一监视器并调用notify为止
notify:唤醒同一对象监视器中调用wait的第一个线程。用于类似饭馆有一个空位后通知所有等待就餐的顾客中的第一位可以入座的情况
notifyAll:唤醒同一对象监视器中调用wait的所有线程,具有最高优先级的线程首先被唤醒并执行。用于类似某个不定期的培训班终于招生满额后,通知所有学员都来上课的情况
class Producer implements Runnable
{
public void run()
{
Q q //定义一个缓冲区
while (true)
{ if(i==0)
{
q.name="zhangsan";
q.sex="male"
}
else
{
q.name="LISI";
q.sex="female"
}
i= (i+1)%2
}
}
}
class Consumer implements Runnable
{ Q q
public void run()
{
while (true)
{
}
}}
class Q
{
String name ="unknown"
String sex ="unknown"
} -
第五课-多线程同步问题
2008-7-01
多线程同步问题
*什么是线程安全
*同步代码块
*同步函数
*代码块与函数间的同步
*死锁问题
45分钟
刚才的程序有一个意外就是tickets的值
还有一种情况是tickets=0的情况时也会出现答应
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
TestThread tt= new TestThread ()new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
}
}
class TestTread implments Runnable//集成接口 runnable类灵活的多
{ int tickets = 100;
public void run()
{
while (true)
{
if (tichests>0)
{ try{Tread.sleep(10);}catch(Excetption e){}_
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}
}
就打印除了0,-1,-2的情况
避免这种情况发生
保证if(tickets>0)
其他线程一定要保证一个线程中的System.println
一个程序中的只能允许一个线程可以执行的代码叫原子代码
只要将原子代码放在一个同步语句块中就可以,保证一个线程进入一个程序代码中
上面的程序中的原子代码是:
if (tichests>0)
{ try{Tread.sleep(10);}catch(Excetption e){}_
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)
只要将它放在synchronized()
即:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
TestThread tt= new TestThread ()new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
}
}
class TestTread implments Runnable//集成接口 runnable类灵活的多
{ int tickets = 100;
String str= new String("")
public void run()
{
while (true)
{
synchronized(str);//任意类型的对象,
{
if (tichests>0)
{ try{Tread.sleep(10);}catch(Excetption e){}_
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}
}
}synchronized(str);//任意类型的对象,线程的标志为是0还是1,开始,对象的标志位是1,已进入代码,标志位制成0,如果又有一个线程进入代码,发现标志位0,就会让出cpu给其他线程,这样就保证了,只能有一个线程进入这个代码。当第一个线程执行完代码后,会把标志位制成1,变为1以后,其他线程就会进入代码块。
标志位也就是锁起位,即监视器
同步,是以牺牲系统的性能为代价的。如果程序没有线程安全问题,尽量不要用多线程。
如果把 String str= new String("")放在run()方法中就会出现不安全现象,也会打印出0,-1,-2
因为每一个线程检查的监视器不是同一个,所以就会有问题
多个线程要同步,他们使用的对象一定是同一个监视器。
还可以用同步函数来实现多线程
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
TestThread tt= new TestThread ()new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
}
}
class TestTread implments Runnable
{ int tickets = 100;
String str= new String("")
public void run()
{
while (true)
{
sale();
}
}
public void sale()
{
if (tichests>0)
{ try{Tread.sleep(10);}catch(Excetption e){}_
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}
这个线程不能实现同步的
如果在函数前加一个 sychronized 关键字
即 public sychronized void sale()
就可以实现同步,如果一个方法前增加了关键字sychronized 只能有一个线程进入这个方法,其他的线程不允许进入这个方法。
sale方法使用的什么标志位?同步对象是this
代码块,函数来实现同步线程启动的内部机制
start()不是cpu马上就执行这个线程。只是线程准备到就绪状态,如果cpu还在原来的线程上执行,将还在继续。
try{Thread.sleep(1);}catch(Exception e){}方法中的监视器就是this
如果一个方法和代码块进行同步,可以在代码块中增加this这样就可以达到同步的作用
即synchronized(this)死锁的问题:
一个线程进入x监视器,另一个线程进入Y监视器,y又等x,x又等待y -
第五课-使用Runnable接口创建多线程
2008-7-01
三、后台线程和联合线程
*如果我们对某个线程对象在启用(调用start方法)之前调用了setDaemon(true)方法,这个线程就变成了后台线程
*对java程序来说,只要还有一个前台线程运行,这个进程就不会结束,如果一个进程中只有后台线程运行,这个进程就会结束。
*pp.join()的作用是把pp所对应的线程合并到调用pp.jion();语句的线程中(主线程)
后台例子:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
Tread tt=new TestTread();
tt.setDaemon(true);
tt.start();
}
}
class TestTread extend Thread//不同
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName())//
}
}
}
联合例子:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
Tread tt=new TestTread();tt.start();
int index=0;
while (true)
{
if(index++==100)
try{tt.join();}catch{Exception e} //异常处理,主线程和子线程合并
//try{tt.join(10000);}catch{Exception e} //异常处理,主线程和子线程合并 10秒
system.out.println("main:"+Thread.currentThread().getName())//
}
}
class TestTread extend Thread//不同
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName())//
}
}
}
runnableclass Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
Thread tt=new Thread(new TestThead());接口对象tt.start();//不再调用thread 中的run()方法,而是调用runnable接口对象的方法
int index=0;
while (true)
{
if(index++==100)
try{tt.join();}catch{Exception e} //异常处理,主线程和子线程合并
//try{tt.join(10000);}catch{Exception e} //异常处理,主线程和子线程合并 10秒
system.out.println("main:"+Thread.currentThread().getName())//
}
}
class TestTread implments Runnable//集成接口 runnable类
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName())//
}
}
}直接用runnable接口实现的线程和直接用Thread对象的线程有什么区别?
调用runnable接口的start方法,就不去调用thread的start方法售票:
线程表示售票
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
new TestThread ().start();
new TestThread ().start();
new TestThread ().start();
new TestThread ().start();
}
}
class TestTread extends Thread//集成接口 runnable类
{ int tickets = 100;
public void run()
{
while (true)
{
if (tichests>0)
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}四个售票点是各自买各自的票,四个对象都有自己的100张票
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
TestThread tt= new TestThread ();
tt.start();
tt.start();
tt.start();
ttstart();
}
}
class TestTread extends Thread//集成接口 runnable类
{ int tickets = 100;
public void run()
{
while (true)
{
if (tichests)
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}
只产生一个对象,只有100张票,启动了4个start,但是代码中只启动了一个线程来启动了start方法
来买票,不能说启动多了start就会启动多个线程。要实现铁路售票,需要
创建一个资源对象,要创建多个线程,我们需要把子对象实现接口Runnable
多个线程处理一个资源对象就需要用接口Runnable
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
TestThread tt= new TestThread ()new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();
new Thread(tt).start();//接受tt对象,然后创建多个线程
}
}
class TestTread implments Runnable//集成接口 runnable类灵活的多
{ int tickets = 100;
public void run()
{
while (true)
{
if (tichests)
system.out.println("run:"+Thread.currentThread().getName()+"is saling ticket"+ tickets
--)//
}
}
}
使用Runnable接口创建多线程
*适合多了相同程序代码的线程去处理统一资源的情况,把虚拟cpu(线程)同程序的代码、数据有效分离
较好地体现了面向对象的设计思想
×可以避免由于Java单继承特性带来的局限。我们经常碰到这样一种情况。即当我们要将已经继承了某个类的子类放入多线程中。由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable
*当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。
*事实上,几乎所有多线程应用都可用Runnable接口方式 -
为老公庆祝生日
2008-6-30
今天是老公的生日,我们买了一个小蛋糕(老公为了省钱不让买,是我坚持买的),我在家里做了两个小菜,恩,感觉很好,最近老公太累了,工作也累,找工作面试也累,吃完饭就看书了,老公辛苦了,我会一直在背后支持你的:)老公加油!!! -
老公的面试
2008-6-23
今天老公去面试,在面试之前只准备了两天的时间看书,不管怎么样吧,面试也是一次学习的机会,能有一次机会和那些高水平的人交流也算是一次提高自己的机会呀,老公加油!我永远支持你。
今天回家后,给我讲述了一下他面试的经过,让他做了4套题,总体感觉还是不错,但是毕竟还是有一些差距的,我鼓励老公,希望老公通过这次面试,能有一些感悟,知道平常应该多学习学习,他平常很少学习,倒是每次都鼓励我学习,就是自己不知道学习,恩,希望这次面试给他提个醒吧:),我永远是老公的后盾,嘿嘿。
-
Linux 系统常用命令
2008-6-23
Linux 系统常用命令格式: command [option] [argument1] [argument2] ...
其中option以“-”开始,多个option可用一个“-”连起来,如“ls -l -a” 与“ls -la”的效果是一样的。根据命令的不同,参数分为可选的或必须的;所有的命令从标准输入接受输入,输出结果显示在标准输出,而错误信息则显示在标准错误输出设备。可使用重定向功能对这些设备进行重定向。
命令在正常执行结果后返回一个0值,如果命令出错可未完全完成,则返回一个非零值(在shell中可用变量$?查看)。 在shell scrīpt中可用此返回值作为控制逻辑的一部分。
帮助命令: man 获取相关命令的帮助信息 例如:man dir 可以获取关于dir的使用信息。 info 获取相关命令的详细使用方法 例如:info info 可以获取如何使用info的详细信息。文件操作: cat 显示文件内容和合并多个文件 clear 清屏 chattr 改变文件属性 chgrp 改变文件组权 chmod 改变文件或目录的权限 chown 改变文件的属权 comm 比较两个已排过序的文件 cp 将文件拷贝至另一文件 dd 从指定文件读取数据写到指定文件 df 报告磁盘空间使用情况 diff 比较两个文本文件,列出行不同之处 du 统计目录/文件所占磁盘空间的大小 file 辨识文件类型 emacs 功能强大的编辑环境 find 搜索文件并执行指定操作(find2) grep 按给定模式搜索文件内容 head 显示指定文件的前若干行 less 按页显示文件 ln 创建文件链接 locate 查找符合条件的文件 more 在终端屏幕按帧显示文本文件 mv 文件或目录的移动或更名 rm/rmdir 删除文件/目录 sed 利用scrīpt来处理文本文件 sort 对指定文件按行进行排序 tail 显示指定文件的最后部分 touch 创建文件 tr 转换字符 vi 全屏编辑器 wc 显示指定文件中的行数,词数或字符数 which 在环境变量 $PATH 设置的目录里查找符合条件的文件
压缩与备份: bzip2/bunzip2 .bz2文件的压缩/解压缩程序 cpio 备份文件 dump 备份文件系统 gzip/gunzip .gz文件的压缩/解压缩程序 gzexe 压缩可执行文件 restore 还原由倾倒(Dump)操作所备份下来的文件或整个文件系统(一个分区) tar 将若干文件存档或读取存档文件 unarj 解压缩.arj文件 zip/unzip 压缩/解压缩 zip文件 zipinfo 列出zip压缩文件的详细信息
磁盘操作: cd/pwd 切换目录/显示当前工作目录 df 显示磁盘的相关信息 du 显示目录或文件的大小 e2fsck 检查ext2/ext3文件系统的正确性 fdisk 对硬盘进行分区 fsck 检查文件系统并尝试修复错误 losetup 设置循环设备 ls 列出目录内容 mkdir 创建目录 mformat 对MS-DOS文件系统的磁盘进行格式化 mkbootdisk 建立目前系统的启动盘 mke2fs 建立ext2文件系统 mkisofs 制作iso光盘映像文件 mount/umount 加载文件系统/卸载文件系统 quota 显示磁盘已使用的空间与限制 sync 将内存缓冲区内的数据写入磁盘 tree 以树状图列出目录的内容
系统操作: alias 设置指令的别名 chkconfig 检查,设置系统的各种服务 clock 调整 RTC 时间 date 显示或设置系统时间与日期 dmesg 显示开机信息 eval 重新运算求出参数的内容 exit 退出目前的shell export 设置或显示环境变量 finger 查找并显示用户信息 free 显示内存状态 hostid 显示主机标识 hostname 显示主机名 id 显示用户标识 kill 删除执行中的程序或工作 last 列出目前与过去登入系统的用户相关信息 logout 退出系统 lsmod 显示已载入系统的模块 modprobe 自动处理可载入模块 passwd 设置用户密码 ps process status 报告程序状况 reboot 重启计算机 rhwo 查看系统用户 rlogin 远程登入 rpm 管理Linux各项套件的程序 shutdown 关机 su switch user 变更用户身份 top 显示,管理执行中的程序 uname 显示系统信息 useradd/userdel 添加用户 / 删除用户 userinfo 图形界面的修改工具 usermod 修改用户属性,包括用户的shell类型,用户组等,甚至还能改登录名 w 显示目前注册的用户及用户正运行的命令 whereis 确定一个命令的二进制执行码,源码及帮助所在的位置 who 列出正在使用系统的用户 whois 查找并显示用户信息
网络通信: arp 网地址的显示及控制 ftp 文件传输 lftp 文件传输 mail 发送/接收电子邮件 mesg 允许或拒绝其他用户向自己所用的终端发送信息 mutt E-mail管理程序 ncftp 文件传输 netstat 显示网络连接、路由表和网络接口信息 pine 收发电子邮件,浏览新闻组 ping 向网络上的主机发送 icmp echo request 包 ssh 安全模式下的远程登录 telnet 远程登录 talk 与另一用户对话 traceroute 显示到达某一主机所经由的路径及所使用的时间 wget 从网络上自动下载文件 write 向其他用户的终端写信息
-
lesson5-java
2008-6-23
第五课
进程和线程
lesson.javaclass Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
new TestTread().run();
while(true)
{
system.out.println("main()"+Thread.currentThread().getName());//thread类静态方法,
返回一个线程类的对象,得到这个线程的名称
}
}
}
class TestTread
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName());//thread类静态方法,
返回一个线程类的对象,得到这个线程的名称
}
}
}执行后,run方法是无限循环,所以main后面的代码没有执行,这是单线程的
如果想实现多线程
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
new Thread().start();启用一个线程,开始执行他的程序代码及run()程序中的代码,但是Thread中的run()方法是一个空的函数没有任何意义,所以要编写一个子类覆盖他的run()方法;
new TestTread().start();//不同,调用Thread的start()方法启用线程开始执行他的程序代码;
while(true)
{
system.out.println("main()"+Thread.currentThread().getName())//thread类静态方法,
返回一个线程类的对象,得到这个线程的名称
}
}
}
class TestTread extend Thread//不同
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName())//thread类静态方法,
返回一个线程类的对象,得到这个线程的名称
}
}
}二、用Thread类创建线程
*要将一段代码在一个新的线程上运行,该代码应该在一个类的run函数中,并且run函数所在的类是Thread类的子类,倒过来看,我们要实现多线程,必须编写一个继承了Tread类的子类,子类要覆盖Thread类中的run函数,在子类的run函数中调用想在新线程上运行的程序代码。
*启动一个新的线程,我们不是直接调用Thread的子类对象的run方法,而是调用Thread子类对象的start(从Thread类的继承到的)方法,Thread类对象的start方法将产生一个新的线程,并在该线程上运行该Thread类对象中的run方法,根据面向对象的运行时的多态性,在该线程上实际运行的是Thread子类(也就是我们写的那个类)对象的run方法
*由于线程的代码段在run方法中,那么该方法执行完成以后线程也就是相应的结束了,因而我们可以通过控制run方法中的循环的条件控制线程的结束。
三、后台线程和联合线程
*如果我们对某个线程对象在启用(调用start方法)之前调用了setDaemon(true)方法,这个线程就变成了后台线程
*对java程序来说,只要还有一个前台线程运行,这个进程就不会结束,如果一个进程中只有后台线程运行,这个进程就会结束。
*pp.join()的作用是吧pp所对应的线程合并到调用pp.jion();语句的线程中
后台例子:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
Tread tt=new TestTread();
tt.setDaemon(true);
tt.start();
}
}
class TestTread extend Thread//不同
{
public void run()
{
while (true)
{
system.out.println("run:"+Thread.currentThread().getName())//
}
}
}
联合例子:
class Threaddemo1
{
public static viod main(String [] args//main方法是在线程上进行的
{
Tread tt=new TestTread();tt.start();
int index=0;
}
}
class TestTread extend Thread//不同
{
public void run()
{
while (true)
{
if(index++==100)
try{tt.join();}catch{Exception e}
system.out.println("run:"+Thread.currentThread().getName())//
}
}
} -
自己的学习计划
2008-6-19
最近工作太忙,很少来更新日志,自己的学习计划也被打乱了,一直没有学习java了,现在公司项目太多,测试人员少,导致每天工作很忙,还经常加班,嗨!自己做了一个初步计划。
1.如果没有特别事情每天要看1-2个小时的书。
2.java也要按计划的学习。
3.考一个项目管理的职称。未来一年的计划(很难实现呀,主要是没有时间学习)
4.我的一个计划了解项目的数据库架构。学习学习,以便更快的了解自己负责的项目。这是未来的几个计划,尽量吧,大家监督我哦,如果日志上没有内容,那就是说明我没有在学习:)
-
最近好忙呀
2008-5-24
最近好忙呀,好久都没有更新我的内容了,家里忙,单位忙,嗨什么时候是头。 -
TD 不能加载附件,不能打开附件
2008-3-13
CEStorageClientImpl::AsyncRequestHandler 加载类型库/DLL 时出错
CEStorageClientImpl::AsyncRequestHandler 加载类型库/DLL 时出错
我们部门内,有一台机器在TD登录后,直接打开附件时提示此错误。
在上传/下载附件时都会提示此错误。
重新下载插件,发现下载项少了很多,
查看activex,发现
Mercury Test Run Scheduler TypeLibrary: 7.0|C:\Program Files\Common Files\Mercury Interactive\TD2000_80\wexectrl.exe|正常
Mercury TestDirector 80 Client UI: 1.0|C:\Program Files\Common Files\Mercury Interactive\TD2000_80\tdclientui80.ocx|正常
Mercury VAPI-XP Type Library: 1.0|C:\Program Files\Common Files\Mercury Interactive\TD2000_80\SRunner.ocx|正常
Mercury Web Client Type Library(v 1.0): 1.0|C:\Program Files\Common Files\Mercury Interactive\TD2000_80\webtdclient80.dll|正常
四个控件中缺少一个:Mercury VAPI-XP Type Library
手工注册SRunner.ocx后,Mercury VAPI-XP Type Library正常。
但是仍然无法直接打开附件。
在重新下载前,用工具进行了垃圾文件和activex 的清理,但是重新下载并尝试打开附件时会提示 :
CEStorageClientImpl::AsyncRequestHandler 控件未注册。
发现重新下载仍缺少控件,手工注册其他缺少的控件后,问题解决。
仍有几个问题不明:
1 为什么重新下载还缺少控件?
2 如何才能确保系统中没有注册的TD的控件(如同没有安装过TD控件一样)?
出问题的客户端目录:
2007-09-19 11:02 <DIR> Dictionary
2007-09-18 13:19 1,134,669 ExpCtrls.dll
2007-09-18 13:19 32,832 ExpHooks.dll
2007-09-18 13:19 1,140,912 OTAClient80.dll
2007-09-18 13:19 96,768 OtaReport.dll
2007-09-18 13:19 121,856 OTAXml.dll
2007-09-18 13:19 474,624 TdComandProtocol.exe
2007-09-18 13:19 501,248 TDInstancemanager.exe
我的最新图片
日历
| |||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | 3 | 4 | ||||||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | |||
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | |||
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | |||
| 26 | 27 | 28 | 29 | 30 | 31 | ||||
搜索标题
最新来客
音乐欣赏
统计信息
- 访问量: 1373
- 日志数: 33
- 图片数: 1
- 建立时间: 2008-02-18
- 更新时间: 2008-09-18

