我突然发现还有很多东西需要我弄明白,比如synchronized这个关键字的用法.因为在我昨天进行创建连接池套接字的研究的时候,发现假如我不弄清楚这个概念,根本就无法进行下去,所以我决定将自己对socket的兴趣先冷却一下,而回过头来看synchronized.
看了一上午的think in java,觉得还是卓有成效的,应该立即写下来加深印象.我感觉自己的大脑可重用性极低,总是需要生成新的记忆对象,从而耗费许多重复劳动.所以象记录,分析,总结这样类似的工作应该多多益善.
要弄清synchronized的用法,首先要知道它是用来解决什么问题的.既然synchronized是同步的意思,那么它当然就是来解决不同步的问题的.下面就举一个不同步的例子来演示可能出现的问题.
在这个例子当中,我们会创建两个线程类.一个叫twocounter,其工作是对两个计数器变量同时进行累加,从1开始,你马上会想道,我们是要用它来实现一个同步.另一个对象叫watcher,顾名思义,是用来做监视工作的,它负责检查twocounter线程中的两个计数器的值是否相等,看起来这似乎是毫无意义的工作,因为既然是同步累加的,那么两个计数器的值怎么可能不相等呢??
但,事实情况不是这样的.我们先来看程序.在看这个程序之前,最好先翻翻think in java的14.2.1,我的程序实际上是根据该节中给出的例子简化的,其中的主类改作了sharing2
class twocounter extends thread {
private int count1 = 0, count2 = 0;
private boolean started=false;
public void start(){
if (!started) file://防止多次对一个线程调用start方法
{
started=true;
super.start();
}
}
public void run() {
while (true) {
count1++;
file://如果twocounter运行到这个时候,cpu时间片被分配给了watcher,那么这个时候watcher读出来的两个计数器的值当然会不一样了,这个可能性是存在的。“这是由线程的本质造成的——它们可在任何时候挂起(暂停)。所以在上述两行的执行时刻之间,有时会出现执行暂停现象。同时,watcher线程也正好跟随着进来,并正好在这个时候进行比较,造成计数器出现不相等的情况.”(think in java)
count2++;
system.out.println("count1="+count1+",count2="+count2);
try {
sleep(500);
} catch (interruptedexception e){}
}
}
public void synchtest() {
sharing2.incrementaccess();
if(count1 != count2)
system.out.println("unsynched");//一旦发现不同步,立即显示
}
}
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){}
}
}
}
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();//打开twocounter线程
new watcher(aaa);//打开watcher线程
}
}
......
count1++;
for(int i=0;i<5000;i++);
count2++;
......
class twocounter extends thread {
public synchronized void run() {
while (true) {
count1++;
count2++;
system.out.println("count1="+count1+",count2="+count2);
try {
sleep(500);
} catch (interruptedexception e){}
}
}
public synchronized void synchtest() {
sharing2.incrementaccess();
if(count1 != count2)
system.out.println("unsynched");//一旦发现不同步,立即显示
}
}略去其它不写,表示从问题到解决其实很简单,呵呵.synchronized(syncobject) {
// this code can be accessed by only
// one thread at a time, assuming all
// threads respect syncobject's lock
} public void run() {
while (true) {
synchronized(this){
count1++;
count2++;
}
system.out.println("count1="+count1+",count2="+count2);
try {
sleep(500);
} catch (interruptedexception e){}
}
}file://注意,synchtest()还是要有synchronized关键字的,考虑一下为什么Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器