synchronized的用法与注意事项

来源:互联网 发布:笔迹鉴定软件 编辑:程序博客网 时间:2024/05/16 09:18

synchronized关键字在java多线程编程过程中非常的有用,不过在编程过程中由于对synchronized的理解不足,也会有很多坑。
synchronized(object)是最常用的方法,它可以锁住需要访问的代码块,使只有一个线程访问而达到同步的目的。例如如下代码:

public class MulThreadTest {    public static int a = 0;    public  void addInt1(){        synchronized(this){            a++;            System.out.println(a);        }    }    public static void main(String[] args){        final MulThreadTest test = new MulThreadTest();        for(int i=0;i<3;i++){            new Thread(new Runnable() {                @Override                public void run() {                    for(int j=0;j<100;j++)                        test.addInt1();                }            }).start();        }    }}

运行上述代码没有问题,synchronized使用this做锁对象,即使用的是引用的对象test做锁对象。因为synchronized包含的代码块包含了方法区里的所有代码,所以方法addInt1()等同如下形式:

    public synchronized void addInt2(){        a++;        System.out.println(a);    }

如果main函数的方法将final对象test放入多线程中,如下:

    public static void main(String[] args) throws InterruptedException {        for(int i=0;i<3;i++){            new Thread(new Runnable() {                @Override                public void run() {                    MulThreadTest test = new MulThreadTest();                    for(int j=0;j<100;j++)                        test.addInt1();                }            }).start();        }    }

此时,运行代码会发现结果不是我们想要的。因为此时运行的每一个线程都有一个锁对象test,他们之间没有做到互斥访问,此时我们就需要更改addInt1()方法如下:

    public void addInt3(){        synchronized (MulThreadTest.class) {            a++;            System.out.println(a);        }    }

将锁加在类上或者声明一个静态对象做为锁对象 :
static Object object = new Object();

总结:
synchronized的多线程使用关键是看哪个作为锁对象,如果锁的不是同一个对象,那么就无法达到同步的目的。

0 0
原创粉丝点击