关于Java中synchronize的理解

缘由:

理解java中synchronized关键字。

指标:理解synchronized的含义。明确synchronized关键字修饰普通方法、静态方法和代码快时锁对象的差异。

有如下一个类A

class A{

       public synchronized void a(){

}

      

    public synchronized void b(){

}

}

然后创建两个对象

A a1 = new A();

A a2 = new A();

然后在两个线程中并发访问如下代码:

Thread1     Thread2

a1.a()         a2.a()  

请问两者能否构成线程同步呢?

如果A的定义是下面这种的呢?

class A{

       public staic synchronized void a(){

}

      

    public static synchronized void b(){

}

}

答案:

第一种情况,不构成同步

第二种情况,够成线程同步

解释:

synchroinzed 关键字修饰普通的方法,针对的是方法所在的对象,锁定的这个方法中的对象只在同一个对象中被锁。synchronized 关键字修饰静态方法,因为静态方法是类方法,和对象无关,所以在不同的对象中也是线程同步的。synchronized修饰代码块,如果为synchronized(this/对象名){}和普通方法是一样的,如果为synchronized(类名.class){}和静态方法是一样的。但是代码同步的仅仅是代码块中的属性或者对象。方法同步的是整个方法体。

扩展:

针对这个问题回顾java中线程的大部分知识:

1.线程的启动方式,new Thread(Runnable对象),其中Runnable是线程驱动的任务,要依附在线程上才能实现

线程行为,否则这个接口并没有特殊之处。

代码如下:

package com.xrc.learnThread;


public class LiftOff implements Runnable{
private static int count = 1000000;
private static int text= 0;
private static int text1= 0;
private static int text2= 0;
private int threadCount = 0;


LiftOff(int i ){
threadCount = i;
}

private synchronized void increase(){
// synchronized  (this){
text ++;
// }
text1 ++;
   
}

private  void increase1(){
// synchronized  (this){
text2 ++;
// }

   
}
public void run() {
         for(int i = 0; i < count ;i++){
        increase();
        increase1();
         
}       
}



public static void main(String[] args){
LiftOff liftOff = new LiftOff(1);
LiftOff liftOff1 = new LiftOff(2);
Thread t1 = new Thread(liftOff);
Thread t2 = new Thread(liftOff);

// Thread t1 = new Thread(liftOff);
// Thread t2 = new Thread(liftOff1);
t1.start();
t2.start();


try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


try {
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(text);
System.out.println(text1);
System.out.println(text2);

}


}

运行结果:

2000000
2000000

1999910


证明了作用于同一对象上的上锁的普通方法是可以实现同步的,同时说明了synchronized仅仅针对的是本方法了面的对象,对其他方法不起作用。

2、使用Executor

有ExecutorService exec = Executors.newCachedThreadPool();

ExecutorService exec = Executors.newFixedThreadPool(5);

ExecutorSercice exec = Executors.singleThreadExecutor();

代码如下:


package com.xrc.learnThread;


public class LiftOff implements Runnable{
private static int count = 10;
private static int text= 0;
private static int text1= 0;
private static int text2= 0;
private int threadCount = 0;


LiftOff(int i ){
threadCount = i;
}

private synchronized void increase(){
// synchronized  (this){
text ++;
System.out.println(threadCount +" : " + text);
// }

   
}

private  void increase1(){
// synchronized  (this){
text2 ++;
// }

   
}
public void run() {
         for(int i = 0; i < count ;i++){
        increase();
        increase1();
         
}       
}

}


package com.xrc.learnThread;


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class ThreadTool {

public static void main(String[] args){
for(int i = 0; i<2;i++){
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new LiftOff(i));
exec.shutdown();
}
}


}


结果如下:

0 : 1
0 : 2
0 : 3
0 : 4
0 : 5
0 : 6
0 : 7
0 : 8
1 : 1
0 : 9
1 : 2
0 : 10
1 : 3
1 : 4
1 : 5
1 : 6
1 : 7
1 : 8
1 : 9
1 : 10
4 : 1
2 : 1
4 : 2
4 : 3
4 : 4
2 : 2
4 : 5
3 : 1
4 : 6
2 : 3
4 : 7
3 : 2
4 : 8
2 : 4
4 : 9
3 : 3
4 : 10
2 : 5
2 : 6
3 : 4
2 : 7
3 : 5
2 : 8
3 : 6
2 : 9
3 : 7
2 : 10
3 : 8
3 : 9
3 : 10


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值