zoukankan      html  css  js  c++  java
  • Synchronized学习

    Syncronized的作用:

    • 能够保证在同一时刻最多只有一个线程执行该段代码,以达到保证并发安全的效果。(有一把锁,持有锁的线程才能执行该段代码)

    Syncronized的地位:

    • Synchronized是java的关键字。
    • 是最基本的互斥同步手段。

    用法:

    • 对象锁,包括方法锁和同步代码块锁。
    • 类锁,指synchronized修饰静态的方法或指定锁为Class对象。

    对象锁

    • 代码块形式要手动指定锁对象
    • 方法锁形式,synchronized修饰普通方法,锁对象默认为this

    未加Synchronized关键字:

    package syncStu;
    
    public class BlockSyncStu implements Runnable{
        static BlockSyncStu blockSyncStu= new BlockSyncStu();
        @Override
        public void run() {
            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 thread1 = new Thread(blockSyncStu,"1111");
            Thread thread2 = new Thread(blockSyncStu,"2222");
            thread1.start();
            thread2.start();
            while ( thread1.isAlive() || thread2.isAlive() ) {}
            System.out.println("finished");
        }
    }
    /*未加Synchronized关键字 :输出 线程1线程2一起执行run方法*/
    我是对象锁的代码块形式。我叫:2222
    我是对象锁的代码块形式。我叫:1111
    2222 运行结束
    1111 运行结束
    finished

     加Synchronized代码块:

    package syncStu;
    
    public class BlockSyncStu implements Runnable{
        static BlockSyncStu blockSyncStu= new BlockSyncStu();
        @Override
        public void run() {
            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 thread1 = new Thread(blockSyncStu,"1111");
            Thread thread2 = new Thread(blockSyncStu,"2222");
            thread1.start();
            thread2.start();
            while ( thread1.isAlive() || thread2.isAlive() ) {}
            System.out.println("finished");
        }
    }
    我是对象锁的代码块形式。我叫:1111
    1111 运行结束
    我是对象锁的代码块形式。我叫:2222
    2222 运行结束
    finished
    执行和结束之间都间隔了3S。
    •  这里的this锁对象,可以使用Object类型的对象代替,有多个目标块需要竞争同一资源的时候,这几个目标块上的对应参数一致,即可。

    Synchronized做方法锁:

    package syncStu;
    
    public class MethodStu implements Runnable{
        static BlockSyncStu blockSyncStu= new BlockSyncStu();
        @Override
        public void run() {
            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 thread1 = new Thread(blockSyncStu,"1111");
            Thread thread2 = new Thread(blockSyncStu,"2222");
            thread1.start();
            thread2.start();
            while ( thread1.isAlive() || thread2.isAlive() ) {}
            System.out.println("finished");
        }
        
    }
    我是对象锁的代码块形式。我叫:1111
    1111 运行结束
    我是对象锁的代码块形式。我叫:2222
    2222 运行结束
    finished
    这个也是依次执行。 

     类锁

    概念:

    • java类可能有很多个对象,但是只有一个Class对象。本质上类锁是一个概念,就是同一时刻只能被一个对象拥有。其他对象会被阻塞。

    形式:

    • synchronized加在static方法上
    • synchronized(.class)代码块
    package syncStu;
    
    public class ClassStaticStu implements Runnable{
        //实例1
        static ClassStaticStu blockSyncStu1= new ClassStaticStu();
        //实例2
        static ClassStaticStu blockSyncStu2= new ClassStaticStu();
        @Override
        public void run() {
            method();
        }
        /**
         *     未加了static关键字
         */
        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 thread1 = new Thread(blockSyncStu1,"1111");
            Thread thread2 = new Thread(blockSyncStu2,"2222");
            thread1.start();
            thread2.start();
            while ( thread1.isAlive() || thread2.isAlive() ) {}
            System.out.println("finished");
        }
    }
    我是对象锁的方法修饰符形式。我叫:1111
    我是对象锁的方法修饰符形式。我叫:2222
    2222 运行结束
    1111 运行结束
    finished
    这种是两个实例对应的线程,并没有被synchronized限制,是一起执行的。 

     把method()方法变为静态方法:

    package syncStu;
    
    public class ClassStaticStu implements Runnable{
        //实例1
        static ClassStaticStu blockSyncStu1= new ClassStaticStu();
        //实例2
        static ClassStaticStu blockSyncStu2= new ClassStaticStu();
        @Override
        public void run() {
            method();
        }
        /**
         *     加了static关键字
         */
        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 thread1 = new Thread(blockSyncStu1,"1111");
            Thread thread2 = new Thread(blockSyncStu2,"2222");
            thread1.start();
            thread2.start();
            while ( thread1.isAlive() || thread2.isAlive() ) {}
            System.out.println("finished");
        }
    }
    我是对象锁的方法修饰符形式。我叫:1111
    1111 运行结束
    我是对象锁的方法修饰符形式。我叫:2222
    2222 运行结束
    finished
    这种的静态方法上加了synchronized就可以。

     --Java高并发之魂:synchronized深度解析 https://www.imooc.com/learn/1086

      

  • 相关阅读:
    python—logger
    print默认在末尾添加一个换行符,但其实也可以不用!
    Python做int()强制类型转换的时候,小数是如何取舍的?
    Python基础之好玩的字符串格式化f-string格式
    【奔走相告】- Github送福利:用户可免费创建私有代码库啦
    我30岁了,转行学编程可以吗? 排除法告诉你答案
    Python基础之好玩的字符串格式化之类C风格
    Python基础之白话说函数
    变量 和 注释
    什么是编程语言,什么是Python解释器
  • 原文地址:https://www.cnblogs.com/jiangym/p/13624280.html
Copyright © 2011-2022 走看看