美文网首页
synchronized锁相关问题

synchronized锁相关问题

作者: 不知名的蛋挞 | 来源:发表于2020-02-25 18:40 被阅读0次

    (1)同一个类中的synchronized method m1和method m2互斥吗?

    public class T {
    
        public static void main(String[] args){
            T t = new T();
            new Thread(t::m1,"t1").start();
            new Thread(t::m2,"t1").start();
        }
    
        // synchronized加在非静态方法上,锁对象即为this
        public synchronized void m1(){
            System.out.println(Thread.currentThread().getName()+"   m1 start.........");
            try {
                Thread.sleep(100000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"   m1 end.........");
        }
    
        public void m2(){
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"   m2");
        }
    }
    

    t1线程执行m1方法时要去读this对象锁,但是t2线程并不需要读锁,两者各管各的,没有交集(不共用一把锁)。

    (2)同一个类中的synchronized method m1可以调用synchronized method m2吗?

    public class T {
    
        public synchronized void m1(){
            System.out.println("m1 start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            m2();
        }
    
        public synchronized void m2(){
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("m2");
        }
    }
    

    一个同步方法可以调用另一个同步方法,一个线程已经拥有某个对象的锁,再次申请的时候仍然会得到该对象的锁,也就是说synchronized获得的锁是可重入的。可以粗浅地理解为同一个线程在已经持有该锁的情况下,可以再次获取锁,并且会在某个状态量上做+1操作。

    (3)子类同步方法synchronized method m可以调用父类的synchronized method m吗?

    public class T {
    
        synchronized void m(){
            System.out.println("m start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("m end");
        }
    }
    
    class TT extends T{
    
        @Override
        synchronized void m(){
            System.out.println("child m start");
            super.m();
            System.out.println("child m end");
        }
    }
    

    子类对象初始化前,会调用父类构造方法,在结构上相当于包裹了一个父类对象,锁对象都是this,而synchronized又是可重入锁,所以是可以的。

    (4)静态同步方法和非静态同步方法互斥吗?

    各玩各的,不是同一把锁,谈不上互斥。

    (5)带有类锁的方法会影响没有上锁的方法的执行吗?

    public class SynchronizedTest {
    
        public static synchronized void test1() {
            int i = 5;
            while (i-- > 0) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    
        public void test2() {
            int i = 15;
            while (i-- > 10) {
                System.out.println(Thread.currentThread().getName() + " : " + i);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
        }
    
        public static void main(String[] args) {
            final SynchronizedTest myt = new SynchronizedTest();
            Thread test1 = new Thread(new Runnable() {
                public void run() {
                    SynchronizedTest.test1();
                    myt.test2();
                }
            }, "test1");
    
            Thread test2 = new Thread(new Runnable() {
                public void run() {
                    SynchronizedTest.test1();
                    myt.test2();
                }
            }, "test2");
            test1.start();
            test2.start();
        }
    }
    

    输出:

    test1 : 4
    test1 : 3
    test1 : 2
    test1 : 1
    test1 : 0
    test2 : 4
    test1 : 14
    test1 : 13
    test2 : 3
    test1 : 12
    test2 : 2
    test1 : 11
    test2 : 1
    test2 : 0
    test1 : 10
    test2 : 14
    test2 : 13
    test2 : 12
    test2 : 11
    test2 : 10
    

    test1有类锁,所以需要thread1执行完thread2才能执行。thread1执行完test1之后,thread2开始执行test1,在这期间,thread1照常执行test2。也就是说:

    • 类锁只能在同一时刻被一个对象拥有。
    • 当某个方法被类锁锁定的时候,不影响其他对象执行该类中的其他方法。

    相关文章

      网友评论

          本文标题:synchronized锁相关问题

          本文链接:https://www.haomeiwen.com/subject/eifmxhtx.html