java 多线程 锁
happenZheng
2010-10-17
关于java 锁的问题:
先上代码: public class Test1{ private int myInt1 = 0; public synchronized void addTen(){ myInt1 += 10; System.out.println("----in addTen: "+myInt1); } public void addTwenty(){ myInt1 += 20; System.out.println("****in addTwenty: "+myInt1); } } 假如现在有两个线程,都调用了类Test1的同一个实例的 addTen()方法,我们知道,这两个线程会互斥访问这个方法;但如果是两个线程,分别访问同一实例的不同方法: addTen() 跟 addTwenty() ,那么synchronized会对方法内操作的成员变量起作用啊吗? 即线程A执行了 myInt1 += 10;后,会继续执行下一行,还是说,存在这种可能,线程B执行了 myInt2 += 20;后,两个方法,输出 myInt1 的值,都是30?? 问题总结: 即对一个加了锁且含有对成员变量进行操作的方法进行访问,JVM会同样的,将对该成员变量实行互斥访问?? |
|
blogzhoubo
2010-10-17
addTwenty方法必须是synchronized的才能实现对myInt1变量的互斥访问。只有一个方法加上synchronized的话,和没加是一个效果。
public class ThreadTest extends Thread{ private String threadName; private Test1 t1; public ThreadTest(String name,Test1 t1){ threadName=name; this.t1=t1; } public void run(){ if(threadName.equals("thread 1")){ for(int i=0;i<10;i++){ t1.addTen(); } }else{ for(int i=0;i<10;i++){ t1.addTwenty(); } } } public static void main(String[] args){ Test1 t1=new Test1(); ThreadTest tr1=new ThreadTest ("thread 1",t1); ThreadTest tr2=new ThreadTest ("thread 2",t1); tr1.start(); tr2.start(); } } class Test1{ private int myInt1 = 0; public synchronized void addTen(){ System.out.println("----before in addTen: "+myInt1); myInt1 += 10; System.out.println("----in addTen: "+myInt1); } public void addTwenty(){ System.out.println("****before in addTwenty: "+myInt1); myInt1 += 20; System.out.println("****in addTwenty: "+myInt1); } } 执行结果: C:\javastudy>java ThreadTest ----before in addTen: 0 ----in addTen: 10 ----before in addTen: 10 ----in addTen: 20 ----before in addTen: 20 ----in addTen: 30 ----before in addTen: 30 ----in addTen: 40 ****before in addTwenty: 40 ****in addTwenty: 60 ****before in addTwenty: 60 ****in addTwenty: 80 ****before in addTwenty: 80 ****in addTwenty: 100 ****before in addTwenty: 100 ****in addTwenty: 120 ----before in addTen: 120 ----in addTen: 130 ----before in addTen: 130 ----in addTen: 140 ----before in addTen: 140 ----in addTen: 150 ----before in addTen: 150 ----in addTen: 160 ----before in addTen: 160 ****before in addTwenty: 160 ****in addTwenty: 180 ****before in addTwenty: 180 ****in addTwenty: 200 ****before in addTwenty: 200 ****in addTwenty: 220 ****before in addTwenty: 220 ****in addTwenty: 240 ----in addTen: 250 ----before in addTen: 250 ----in addTen: 260 ****before in addTwenty: 260 ****in addTwenty: 280 ****before in addTwenty: 280 ****in addTwenty: 300 C:\javastudy> |
|
happenZheng
2010-10-17
嗯,谢谢楼上回答
|
|
twypx
2010-11-04
将myInt1用AtomicInteger原子类型试试呢,那么下面的方法就不需要加锁了
|
|
奇林醉
2011-07-14
blogzhoubo 写道 addTwenty方法必须是synchronized的才能实现对myInt1变量的互斥访问。只有一个方法加上synchronized的话,和没加是一个效果。
public class ThreadTest extends Thread{ private String threadName; private Test1 t1; public ThreadTest(String name,Test1 t1){ threadName=name; this.t1=t1; } public void run(){ if(threadName.equals("thread 1")){ for(int i=0;i<10;i++){ t1.addTen(); } }else{ for(int i=0;i<10;i++){ t1.addTwenty(); } } } public static void main(String[] args){ Test1 t1=new Test1(); ThreadTest tr1=new ThreadTest ("thread 1",t1); ThreadTest tr2=new ThreadTest ("thread 2",t1); tr1.start(); tr2.start(); } } class Test1{ private int myInt1 = 0; public synchronized void addTen(){ System.out.println("----before in addTen: "+myInt1); myInt1 += 10; System.out.println("----in addTen: "+myInt1); } public void addTwenty(){ System.out.println("****before in addTwenty: "+myInt1); myInt1 += 20; System.out.println("****in addTwenty: "+myInt1); } } 执行结果: C:\javastudy>java ThreadTest ----before in addTen: 0 ----in addTen: 10 ----before in addTen: 10 ----in addTen: 20 ----before in addTen: 20 ----in addTen: 30 ----before in addTen: 30 ----in addTen: 40 ****before in addTwenty: 40****in addTwenty: 60 ****before in addTwenty: 60 ****in addTwenty: 80 ****before in addTwenty: 80 ****in addTwenty: 100 ****before in addTwenty: 100 ****in addTwenty: 120 ----before in addTen: 120 ----in addTen: 130 ----before in addTen: 130 ----in addTen: 140 ----before in addTen: 140 ----in addTen: 150 ----before in addTen: 150 ----in addTen: 160 ----before in addTen: 160 ****before in addTwenty: 160 ****in addTwenty: 180 ****before in addTwenty: 180 ****in addTwenty: 200 ****before in addTwenty: 200 ****in addTwenty: 220 ****before in addTwenty: 220 ****in addTwenty: 240 ----in addTen: 250 ----before in addTen: 250 ----in addTen: 260 ****before in addTwenty: 260 ****in addTwenty: 280 ****before in addTwenty: 280 ****in addTwenty: 300 C:\javastudy> 我在自己myeclipse上执行了 ----before in addTen: 0 ----in addTen: 10 ----before in addTen: 10 ----in addTen: 20 ----before in addTen: 20 ----in addTen: 30 ----before in addTen: 30 ****before in addTwenty: 0****in addTwenty: 60 ****before in addTwenty: 60 ****in addTwenty: 80 ****before in addTwenty: 80 ****in addTwenty: 100 ****before in addTwenty: 100 ****in addTwenty: 120 ****before in addTwenty: 120 ****in addTwenty: 140 ****before in addTwenty: 140 ****in addTwenty: 160 ****before in addTwenty: 160 ****in addTwenty: 180 ****before in addTwenty: 180 ****in addTwenty: 200 ****before in addTwenty: 200 ****in addTwenty: 220 ****before in addTwenty: 220 ****in addTwenty: 240 ----in addTen: 40 ----before in addTen: 240 ----in addTen: 250 ----before in addTen: 250 ----in addTen: 260 ----before in addTen: 260 ----in addTen: 270 ----before in addTen: 270 ----in addTen: 280 ----before in addTen: 280 ----in addTen: 290 ----before in addTen: 290 ----in addTen: 300 这是为什么呢 ? |