深入理解使用synchronized同步方法和同步代码块的区别

一.代码块和方法之间的区别

首先需要知道代码块和方法有什么区别:

构造器和方法块,构造器可以重载也就是说明在创建对象时可以按照不同的构造器来创建,那么构造器是属于对象,而代码块呢他是给所有的对象初始化的。底下看一个列子:

public class Constructor_Methodblock {
    private int num;
    private String str;
    //构造器
    public Constructor_Methodblock(int num,String str){
        System.out.println("\n************构造器****************");
        System.out.println("在进入构造器之前成员变量的值为num:"+this.num+"str: "+this.str);
        this.str=str;
        this.num=num;
        System.out.println("赋值之后num为"+num+"str为"+str);
    }
    //方法块
    {
        System.out.println("\n************代码块****************");
        System.out.println("在进入方法块之前成员变量的值为num:"+num+"str: "+str);
        num=1;
        str="li";
        System.out.println("赋值之后num为"+num+"str为"+str);
    }

    public static void main(String[] args) {
        new Constructor_Methodblock(2,"fei");
    }
}

 结果为:

 发现代码块比构造器早执行,而且代码块是所有的对象都要执行的。

 现在我们对代码块和方法有了一定的了解,那么同步方法有什么缺点使得我们需要同步代码块呢?

二.同步方法的缺点

来想象一个这样的情况:一个方法其中有一部分是需要计算数据花费时间不是那么长但是还有一部分他不需要处理数据但是他需要花费大量的时间,那么如果我们直接将这个方法同步化会导致整体的代码性能下降,而我们仅仅将这个计算数据部分同步保证共享数据计算没有问题,那么代码性能是不是就上去了呢?

来看直接同步化方法:

public class SynFun extends Thread {
    private int num=10;//共享数据
    @Override
     public void run(){
        try {
            this.fun();//调用同步方法
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void fun() throws InterruptedException {
        //使用睡眠来模拟一下复杂但是对数据处理没有关系的部分,睡眠三秒
        Thread.sleep(3000);
                System.out.println("修改前的num为"+num);
                num--;
                System.out.println("修改后的num为"+num);
        System.out.println("*************");
    }

    public static void main(String[] args) {

        SynFun synFun=new SynFun();
        Thread t1=new Thread(synFun);
        Thread t2=new Thread(synFun);
        t1.start();
        t2.start();

    }
}

结果为:出现结果时,先等待了三秒出现了第一个结果,在等待了三秒又出现了第二个结果。

改进一下:

public  void fun() throws InterruptedException {
        //使用睡眠来模拟一下复杂但是对数据处理没有关系的部分,睡眠三秒
        Thread.sleep(3000);
        synchronized (this){
            System.out.println("修改前的num为"+num);
            num--;
            System.out.println("修改后的num为"+num);
        }
        System.out.println("*************");
    }

 

就是利用同步化代码块,将共享数据处理的部分同步起来,而其他的部分就让他去交叉运行吧。

结果是一样的,但是出现结果就是三秒以后直接出现两个答案,说明整体性能直接上去了。

 

 ******************************************************题外话***********************************************************

Java多线程专题已经已经发表了五篇博客了,不少前辈(其实我还是一个大二的学生)都给出了很好的讲解和指导,在这里真的非常感谢你们。

1   if(对我的博客感兴趣){
2         点赞+关注;
3     }else{
4         没有else
5     }

 

posted on 2018-10-17 20:16  真正的小明被占用了  阅读(7184)  评论(0编辑  收藏  举报

导航