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

这是为什么呢 ?
Global site tag (gtag.js) - Google Analytics