美文网首页
Java多线程方法锁机制

Java多线程方法锁机制

作者: 秋风落叶黄 | 来源:发表于2017-04-28 16:32 被阅读0次

本文主要介绍在多线程中对于普通方法和静态方法加锁调用产生的情况。
结论:

(1)非静态方法锁默认为this也就是作用在对象上,静态方法的锁对应 Class实例(类加载会生成一个Class实例)
(2)某一个时刻内,只有一个线程可以持有锁,无论几个方法

下面主要是验证这两个结论:

1.两个普通同步方法,开启两个线程调用

    class Number{
        public synchronized void getOne()  {
            System.out.println("one");
        }
    
        public synchronized  void getTwo(){
            System.out.println("two");
        }
    }
      public static void main(String[] args) {
            Number number = new Number();
            
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getOne();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getTwo();
                }
            }).start();
        }

运行结果为:

one
two

2.在上面的基础上修改getOne()方法添加Thread.sleep()

     public synchronized void getOne()  {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("one");
        }

运行结果为:

 one
 two

说明了两个方法调用的是同一个锁,锁先被线程一调用了,导致线程二处于等待状态,当线程一执行完后,线程二才能继续执行

3. 新增getThree()方法,同时开启三个线程调用这三个方法

    public class TestThread8Monitor {
        public static void main(String[] args) {
            Number number = new Number();
            
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getOne();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getTwo();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getThree();
                }
            }).start();
        }
    }
    
    class Number{
        public synchronized void getOne()  {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("one");
        }
    
        public  synchronized  void getTwo(){
            System.out.println("two");
        }
    
        public void getThree(){//普通未加锁方法
            System.out.println("three");
        }
    }

运行结果:

three
one
two

说明:普通方法不受线程锁的影响,线程三直接执行,无须等待前面的线程释放锁

4.创建number的两个实例分别调用getOne()和getTwo()方法

    public class TestThread8Monitor {
    
        public static void main(String[] args) {
            Number number = new Number();
            Number number2 = new Number();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getOne();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number2.getTwo();
                }
            }).start();
        }
    }
    
    class Number{
        public synchronized void getOne()  {
            try {
                Thread.sleep(3000);//等待3秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("one");
        }
    
        public  synchronized  void getTwo(){
            System.out.println("two");
        }
    }

运行结果: two one
说明:调用加锁的普通方法,上锁的是this,也就是该对象,因此两个线程分别调用两个不同的对象,两者之间不存在互斥等待问题。

5.将getOne()改为静态方法,两个线程同时调用一个对象的不同方法

    public class TestThread8Monitor {
    
        public static void main(String[] args) {
            Number number = new Number();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getOne();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    number.getTwo();
                }
            }).start();
        }
    }
    
    class Number{
        public static synchronized void getOne()  {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("one");
        }
    
        public  synchronized  void getTwo(){
            System.out.println("two");
        }
    }

运行结果: two one

说明: 静态方法锁和普通方法锁的目标不同。

6.同时将两个方法设置为静态方法,两个线程调用同一对象的两个方法

   public class TestThread8Monitor {
    public static void main(String[] args) {
        Number number = new Number();
        Number number2 = new Number();
        new Thread(new Runnable() {
            @Override
            public void run() {
                number.getOne();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                number2.getTwo();
            }
        }).start();
    }
}

class Number{
    public static synchronized void getOne()  {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("one");
    }

    public static synchronized  void getTwo(){
        System.out.println("two");
    }
}

运行结果: one two
说明:静态方法加锁是在类上的,也就是类的Class实例。因此两个线程调用两个对象的不同方法,结果却需要互斥调用

相关文章

  • java 多线程总结篇4——锁机制

    在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制。Java提供了多种多线程锁机制的实现方...

  • JAVA锁机制

    在开发Java多线程应用程序中,各个线程之间由于要共享资源,必须用到锁机制。Java提供了多种多线程锁机制的实现方...

  • Java多线程方法锁机制

    本文主要介绍在多线程中对于普通方法和静态方法加锁调用产生的情况。结论: (1)非静态方法锁默认为this也就是作用...

  • Java 中的各种锁

    多线程开发离不开各种锁,下面总结下Java和JDK提供的各种锁机制 synchronized synchroniz...

  • java锁

    前言 java并发是多线程开发中经常遇到的问题,对并发的处理,java提供了一系列的方法.机制,其中锁是其中的一个...

  • 由浅深入理解java多线程,java并发,synchronize

    由浅深入理解java多线程,java并发,synchronized实现原理及线程锁机制 [TOC] 多进程是指操作...

  • Java的锁到底怎么用

    本文章主要讲的是Java多线程加锁机制,有两种: Synchronized Lock synchronized锁是...

  • Java多线程(十五)---锁的内存语义

    移步java多线程系列文章锁是Java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向...

  • JVM系列之:对象的锁状态和同步

    简介 锁和同步是java多线程编程中非常常见的使用场景。为了锁定多线程共享的对象,Java需要提供一定的机制来实现...

  • JVM系列之:对象的锁状态和同步

    简介 锁和同步是java多线程编程中非常常见的使用场景。为了锁定多线程共享的对象,Java需要提供一定的机制来实现...

网友评论

      本文标题:Java多线程方法锁机制

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