• Java中使用synchronized多线程同步的实例


    synchronized关键字

    Java提供了synchronized关键字,用于控制台多线程同步。
    可以加在方法上,在方法名前加synchronized
    也可以加在一段代码块,synchronized (xxx) { ... },其中xxx为对象,一般为this, Xxx.class或者某个对象实例。

    实例1

    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.TimeUnit;
    
    /**
     * synchronized非static方法,多线程不同对象访问
     * 并未同步执行
     * 因为MyThread的run方法中new了不同的MySync对象
     *
     * @author cdfive
     */
    public class SynchoronizedDemo1 {
    
        public static void main(String[] args) {
            int threadNum = 3;
            for (int i = 0; i < threadNum; i++) {
                MyThread myThread = new MyThread();
                myThread.start();
            }
        }
    
        static class MySync {
    
            public synchronized void test() {
                long start = System.currentTimeMillis();
                System.out.println(String.format("%s start", Thread.currentThread().getName()));
                try {
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
            }
        }
    
        static class MyThread extends Thread {
    
            @Override
            public void run() {
                MySync sync = new MySync();
                sync.test();
            }
        }
    }
    

    实例2

    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 在非static方法里的synchronized this,多线程不同对象访问
     * 并未同步执行
     * 跟SynchoronizedDemo1类似,因为MyThread的run方法中new了不同的MySync对象
     *
     * @author cdfive
     */
    public class SynchoronizedDemo2 {
    
        public static void main(String[] args) {
            int threadNum = 3;
            for (int i = 0; i < threadNum; i++) {
                MyThread myThread = new MyThread();
                myThread.start();
            }
        }
    
        static class MySync {
    
            public void test() {
                synchronized (this) {
                    long start = System.currentTimeMillis();
                    System.out.println(String.format("%s start", Thread.currentThread().getName()));
                    try {
                        TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
                }
            }
        }
    
        static class MyThread extends Thread {
    
            @Override
            public void run() {
                MySync sync = new MySync();
                sync.test();
            }
        }
    }
    

    实例3

    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.TimeUnit;
    
    /**
     * synchronized非static方法,多线程相同对象访问
     * 同步执行成功
     *
     * @author cdfive
     */
    public class SynchoronizedDemo3 {
    
        public static void main(String[] args) {
            int threadNum = 3;
            MySync mySync = new MySync();
            for (int i = 0; i < threadNum; i++) {
                MyThread myThread = new MyThread(mySync);
                myThread.start();
            }
        }
    
        static class MySync {
    
            public synchronized void test() {
                long start = System.currentTimeMillis();
                System.out.println(String.format("%s start", Thread.currentThread().getName()));
                try {
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
            }
        }
    
        static class MyThread extends Thread {
    
            private MySync mySync;
    
            public MyThread(MySync mySync) {
                this.mySync = mySync;
            }
    
            @Override
            public void run() {
                mySync.test();
            }
        }
    }
    

    实例4

    /**
     * 在非static方法里的synchronized this,多线程相同对象访问
     * 同步执行成功
     *
     * @author cdfive
     */
    public class SynchoronizedDemo4 {
    
        public static void main(String[] args) {
            int threadNum = 3;
            MySync mySync = new MySync();
            for (int i = 0; i < threadNum; i++) {
                MyThread myThread = new MyThread(mySync);
                myThread.start();
            }
        }
    
        static class MySync {
    
            public synchronized void test() {
                long start = System.currentTimeMillis();
                System.out.println(String.format("%s start", Thread.currentThread().getName()));
                try {
                    TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
            }
        }
    
        static class MyThread extends Thread {
    
            private MySync mySync;
    
            public MyThread(MySync mySync) {
                this.mySync = mySync;
            }
    
            @Override
            public void run() {
                mySync.test();
            }
        }
    }
    

    实例5

    import java.util.concurrent.ThreadLocalRandom;
    import java.util.concurrent.TimeUnit;
    
    /**
     * 在非static方法里的synchronized Xxx.class,多线程不同对象访问
     * 同步执行成功
     * synchronized Xxx.class相当于全局锁
     *
     * @author cdfive
     */
    public class SynchoronizedDemo5 {
    
        public static void main(String[] args) {
            int threadNum = 3;
            for (int i = 0; i < threadNum; i++) {
                MyThread myThread = new MyThread();
                myThread.start();
            }
        }
    
        static class MySync {
    
            public void test() {
                synchronized (SynchoronizedDemo5.class) {
                    long start = System.currentTimeMillis();
                    System.out.println(String.format("%s start", Thread.currentThread().getName()));
                    try {
                        TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(3));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(String.format("%s end,cost=%dms", Thread.currentThread().getName(), (System.currentTimeMillis() - start)));
                }
            }
        }
    
        static class MyThread extends Thread {
    
            @Override
            public void run() {
                MySync sync = new MySync();
                sync.test();
            }
        }
    }
    

    以上实例synchronized同步方法,this,Xxx.class时,多线程使用相同或不同对象访问,有不同的结果,在日常开发中需要注意。

  • 相关阅读:
    MySQL视图——学习笔记及实验
    小学生四则运算自动刷题库优化升级
    软件工程小项目——小学生四则运算自动刷题库
    笔记--运算符、表达式和语句
    笔记--基本数据类型与数组
    笔记--java入门
    原因: java.lang.ClassNotFoundException: Hello
    使用gopm代替go get 解决go包卡慢的问题
    调用微信截图功能c# 截图带扩展名
    如何用golang搜索抓取淘宝商品
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/14272057.html
Copyright © 2020-2023  润新知