美文网首页
多线程synchronized的使用

多线程synchronized的使用

作者: IFLEU | 来源:发表于2019-01-09 23:19 被阅读0次

      在多线程的使用中,关键字synchronized的使用主要有:1、修饰代码块;2修饰方法。

    1、修饰代码块synchronized(obj)

      这里主要有synchronized(this)和synchronized(obj),而()中的即为得到的锁,判断锁是否为同一个即判断是否为同步代码块。它的主要判断是锁对象是否相等,对于值类型而言看值是否相同,对于对象类型则看是否为相同的引用,综合而言即为争夺锁的两个obj是否==。
    以下是代码实例:
       1、synchronized(this):this是当前类的对象实例,所以要判断争夺锁的两个obj是否为同一个对象实例,如果为同一个对象实例,则它们之间互斥。

    public class SynchronizedTest implements Runnable{
    
        public void method(){
            try {
                //这里是同步代码块
                synchronized (this){
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(5000);
                }
                System.out.println("5秒已结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            //争夺锁的两个对象
            SynchronizedTest synchronizedTest1 = new SynchronizedTest();
            //这里的对象其实是同一个
            //1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
            //两个不同对象
            //2️⃣SynchronizedTest synchronizedTest2 =  new SynchronizedTest();
            Thread thread1 = new Thread(synchronizedTest1);
            Thread thread2 = new Thread(synchronizedTest2);
            thread1.start();
            thread2.start();
        }
    }
    

       1️⃣时得到的为

    K%SHK8CXN{JOBY2%Y949F_V.png
       2️⃣时得到的为 KP13Q2L3FZQ3J9}W{UEIM9J.png
      synchronized(this)中的this是类的对象实例,在1️⃣中synchronizedTest1创建了一个对象实例,synchronizedTest2只是去引用了这个对象,即为同一个对象,所以它们是同一个锁,会出现互斥现象;而在2️⃣中synchronizedTest2又重新创建了一个新的对象,和synchronizedTest1不是同一个锁,所以不会出现互斥。
       2、synchronized(obj):正如开始所说,obj如果是值类型则判断值是否相同,对象则同this,总体而言则是判断调用synchronized的obj在内存中的地址是否相同,如果相同,则是争夺同一把锁。synchronized(SynchronizedTest.class),SynchronizedTest.class的地址相同,线程调用同步代码块都会互斥。

    2、修饰方法synchronized

      修饰方法主要分为非静态方法和静态方法:
      修饰非静态方法就是看类对象是否是同一个,与synchronized(this)相同。

    public class SynchronizedTest implements Runnable {
        public synchronized void method(){
            try {
                System.out.println(Thread.currentThread().getName());
                Thread.sleep(5000);
                System.out.println("5秒已结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            //争夺锁的两个对象
            SynchronizedTest synchronizedTest1 = new SynchronizedTest();
             //这里的对象其实是同一个
            //1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
            //两个不同对象
            //2️⃣SynchronizedTest synchronizedTest2 =  new SynchronizedTest();
            Thread thread1 = new Thread(synchronizedTest1);
            Thread thread2 = new Thread(synchronizedTest2);
            thread1.start();
            thread2.start();
        }
    }
    
       1️⃣时得到的为 3K@71FQK{(F3NB2F@3PX3CO.png
       2️⃣时得到的为 1111.png
    public class SynchronizedTest implements Runnable {
        public static synchronized void method(){
            try {
                System.out.println(Thread.currentThread().getName());
                Thread.sleep(5000);
                System.out.println("5秒已结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void run() {
            method();
        }
    
        public static void main(String[] args) {
            //争夺锁的两个对象
            SynchronizedTest synchronizedTest1 = new SynchronizedTest();
             //这里的对象其实是同一个
            //1️⃣SynchronizedTest synchronizedTest2 = synchronizedTest1;
            //两个不同对象
            //2️⃣SynchronizedTest synchronizedTest2 =  new SynchronizedTest();
            Thread thread1 = new Thread(synchronizedTest1);
            Thread thread2 = new Thread(synchronizedTest2);
            thread1.start();
            thread2.start();
        }
    }
    

      修饰静态方法则与SynchronizedTest.class相同。

      1️⃣2️⃣均会得到 222.png
    由此,对于synchronized锁的判断主要是看它们的锁是否是同一个锁,即在内存中的地址是否相同。

    修饰非静态方法时,在同一个对象实例中才锁
    修饰静态方法时,即同.class
    synchronized(obj)根据运行过程中的两个obj是否==来判断是否是同一个锁

    相关文章

      网友评论

          本文标题:多线程synchronized的使用

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