多线程学习-synchronized 下

上一篇列举了多个线程对同一个对象的竞态代码区的synchronized的同步效果和机制,这篇来验证下,多个线程,多个对象synchronized的同步问题

首先明确一点,synchronized的同步机制是建立在对象上的,不同对象是不会有影响的,这也是实际的应用场景吻合。

多线程 多个对象  synchronized

public class ThreadDemo2 {
    /**
     * 竞态方法 method1
     *
     * */
    public  synchronized void method1(){
        try{
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName()+"  over");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    /**
     * 普通方法 method2
     *
     * */
    public   void method2(){
        System.out.println(Thread.currentThread().getName()+"  normal  method");
    }

    /**
     * 竞态方法 method3
     *
     * */
    public  synchronized void method3(){
        try{
            System.out.println(Thread.currentThread().getName());
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName()+"  over");
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    public static  void main(String[] args){
        final ThreadDemo2 threadDemo1 = new ThreadDemo2();
        final ThreadDemo2 threadDemo2 = new ThreadDemo2();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                threadDemo1.method1();
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                threadDemo2.method1();
            }
        },"t2");

        t1.start();
        t2.start();
    }
}

运行结果:

t1
t2
t2  over
t1  over

可以看出两个线程同时执行了不同对象的竞态方法,如果不同对象在多线程下还想实现同步,那就需要类级别的锁(或者对竞态的区域加static修饰),性能狠狠狠差,相当于无论谁无论在哪调用这个class的对象都需要获得锁权限。我觉得加这种级别的锁的人要么是喝多了,要么是胆子太大。

synchronized 同步或者竞态代码块的粒度要保持好

public class ThreadDemo3 {
    /**
     * method1
     *
     * */
    public   void method1(){
        try{
            //TODO 这里是公共区域 不具有竞争属性 可以做很多准备工作
            System.out.println(Thread.currentThread().getName()+"---out the door");
            synchronized(this) {//上锁 关门
                //TODO 这里是竞态区域  需要获取锁才能进来 同样是锁的是对象
                System.out.println(Thread.currentThread().getName()+"---in the door");
                Thread.sleep(5000);
            }
            System.out.println(Thread.currentThread().getName()+"  over");
        }catch(Exception e){
            e.printStackTrace();
        }
    }


    public static  void main(String[] args){
        final ThreadDemo3 threadDemo1 = new ThreadDemo3();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                threadDemo1.method1();
            }
        },"t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                threadDemo1.method1();
            }
        },"t2");

        t1.start();
        t2.start();
    }
}

运行结果

t1---out the door
t1---in the door
t2---out the door
t2---in the door
t1  over

t2  over

从结果可以看出 t1 和 t2 虽然都进入了method1 但是t2要在门外等t1在门里面把事情办完才能进去,与之前的在方法上同步,这个粒度要小一些,可以在公共区域处理进门前的逻辑

synchronized 虽然好用但是也要注意粒度,注意场合!






猜你喜欢

转载自blog.csdn.net/leeahuamsg/article/details/79457628