• synchronized关键字详解(一)


    synchronized官方定义:

    同步方法支持一种简单的策略防止线程干扰和内存一致性错误,如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都是通过同步方法完成的(这一个synchronized关键字完成的)。

    通俗的来讲:

    synchronized关键字:能够保证同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。

    synchronized的两个用法:

    1.对象锁:包括方法锁(默认锁对象是当前实例对象)和同步代码块锁(自己指定锁的对象);

    2.类锁:synchronized修饰的静态的方法或指定锁为Class对象;

    代码展示:

    对象锁:针对的是同一个对象(即下列中的instance对象),如果是两个不同的对象,对象锁就不能起到同步的作用(可以自己创两个对象测试),而类锁可以。

     * 对象锁的代码块形式
     * @author Administrator
     *
     */
    public class SynchronizeTest01 implements Runnable{
        static SynchronizeTest01 instance = new SynchronizeTest01();
        Object obj = new Object(); @Override
    public void run() {
          //锁自定义对象
          synchronized (obj) {
                System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"玩完了");
            }
          //第一种锁当前对象
            /*synchronized (this) {
                System.out.println("我是对象锁代码块,我叫"+Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"玩完了");
            }*/
        }
        public static void main(String[] args) {
            Thread t1 = new Thread(instance,"线程一");
            Thread t2 = new Thread(instance,"线程二");
            t1.start();
            t2.start();
            while(t1.isAlive()||t2.isAlive()) {
                
            }
            System.out.println("执行结束");
        }
    }

    /**
     * 普通方法锁形式
     * @author Administrator
     *
     */
    public class SynchronizeTest02 implements Runnable{
        static SynchronizeTest02 instance = new SynchronizeTest02();
        @Override
        public void run() {
            //调用加synchronized关键字的普通方法
            method();
        }
        public synchronized void method() {
            System.out.println("我是普通方法锁,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "玩完了");
        }
        public static void main(String[] args) {
            Thread t1 = new Thread(instance,"线程一");
            Thread t2 = new Thread(instance,"线程二");
            t1.start();
            t2.start();
            while(t1.isAlive()||t2.isAlive()) {
                
            }
            System.out.println("执行结束");
        }
    }

    普通方法锁形式

     

    类锁:每个类可能会有多个对象,但是每个类只有一个Class对象,所以类锁的本质就是对Class对象的锁,类锁在同一时刻只能被一个对象拥有(对象锁不可以)

    类锁的第一种形式:在静态方法上加锁,并创建了两个对象,依然可以解决并发问题。

    /**
     * 
     * 类锁的第一种形式:静态方法锁形式
     * @author Administrator
     *
     */
    public class SynchronizeTest02 implements Runnable{
        static SynchronizeTest02 instance1 = new SynchronizeTest02();
        static SynchronizeTest02 instance2 = new SynchronizeTest02();
        @Override
        public void run() {
            //调用加synchronized关键字的静态方法
            method();
        }
        public static synchronized void method() {
            System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "玩完了");
        }
        public static void main(String[] args) {
            Thread t1 = new Thread(instance1,"线程一");
            Thread t2 = new Thread(instance2,"线程二");
            t1.start();
            t2.start();
            while(t1.isAlive()||t2.isAlive()) {
                
            }
            System.out.println("执行结束");
        }
    }

     类锁的第二种形式:

    /**
     * 
     * 类锁的第二种形式:代码块锁.Class形式
     * @author Administrator
     *
     */
    public class SynchronizeTest03 implements Runnable{
        static SynchronizeTest03 instance1 = new SynchronizeTest03();
        static SynchronizeTest03 instance2 = new SynchronizeTest03();
        @Override
        public void run() {
            //调用加synchronized关键字的普通方法
            method();
        }
        public void method() {
            synchronized (SynchronizeTest03.class) {
                System.out.println("我是静态方法锁,我叫" + Thread.currentThread().getName());
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "玩完了");
                }
        }
        public static void main(String[] args) {
            Thread t1 = new Thread(instance1,"线程一");
            Thread t2 = new Thread(instance1,"线程二");
            t1.start();
            t2.start();
            while(t1.isAlive()||t2.isAlive()) {
                
            }
            System.out.println("执行结束");
        }
    }

    锁代码块中锁.Class形式

  • 相关阅读:
    基础语法 -实验楼
    JavaSE案例-Bank
    初识Java
    Java学习大纲-0412更新
    增量法
    蛮力法
    Host‘116.77.33.xx’is not allowed to connect to this MySQL server
    Maven坐标
    HotSpot虚拟机对象创建
    程序计数器为什么是线程私有的?
  • 原文地址:https://www.cnblogs.com/YpfBolg/p/10805496.html
Copyright © 2020-2023  润新知