• 18.synchronized


    同步的前提:

    1. 必须要有两个或者两个以上的线程
    2. 必须是多个线程使用同一个锁
    3. 必须保证同步中只能有一个线程在运行
    • 好处:解决了多线程的安全问题
    • 弊端:多个线程需要判断锁,较为消耗资源、抢锁的资源。
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * synchronized 实现线程间的同步,对同步的代码加锁,似的每次只能有一个线程进入同步块
     * 可以保证线程间的可见性和有序性
     * · 指定加锁对象:对给定对象加锁,进入同步代码前要获取给定对象的锁
     * · 直接作用于实例方法:相当于对当前实例加锁,进入同步代码前要获取当前实例的锁
     * · 直接作用于静态方法:相当于对当前类加锁,进入同步代码前要获取当前类的锁 -- class文件
     */
    public class SynchronizedDemo {
        private static int size = 0;
        private static List<Integer> arrayOne = new ArrayList<>(10000);
        private static List<Integer> arrayTwo = new ArrayList<>(10000);
        public static synchronized void increase(){ //synchronized作用于一个实例方法
            size++;
        }
        public static void main(String[] args) throws InterruptedException{
    
            for (int i = 0; i < 10000; i++) {
                arrayOne.add(0);
                arrayTwo.add(0);
            }
            Thread threadOne = new Thread(() -> {
                int length = arrayOne.size();
                for (int i = 0; i < length; i++) {
                    if (arrayOne.get(i).intValue()==0){
                        increase();
                    }
                }
            });
            Thread threadTwo = new Thread(() -> {
                int length = arrayTwo.size();
                for (int i = 0; i < length; i++) {
                    if (arrayTwo.get(i).intValue()==0){
                        increase();
                    }
                }
            });
            threadOne.start();
            threadTwo.start();
            threadOne.join();
            threadTwo.join();
            System.out.println(size);
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * Runnable
     */
    public class SynchronizedDemo1 {
        private static int size = 0;
        private static List<Integer> arrayOne = new ArrayList<>(10000);
        private static List<Integer> arrayTwo = new ArrayList<>(10000);
    
        public static class AccountSyncBad implements Runnable{
            synchronized void increase(){ //synchronized
                size++;
            }
            @Override
            public void run() {
                int length = arrayOne.size();
                for (int i = 0; i < length; i++) {
                    if (arrayOne.get(i).intValue()==0){
                        increase();
                    }
                }
            }
        }
        public static void main(String[] args) throws InterruptedException{
            for (int i = 0; i < 10000; i++) {
                arrayOne.add(0);
                arrayTwo.add(0);
            }
            AccountSyncBad accountSyncBad = new AccountSyncBad();
            Thread threadOne = new Thread(accountSyncBad);
            Thread threadTwo = new Thread(accountSyncBad);
            threadOne.start();
            threadTwo.start();
            threadOne.join();
            threadTwo.join();
            System.out.println(size);
        }
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 两个线程指向不同的Runnable实例,这两个线程使用的是两把不同的锁,无法保证线程安全
     */
    public class SynchronizedDemo2 {
        private static int size = 0;
        private static List<Integer> arrayOne = new ArrayList<>(10000);
        private static List<Integer> arrayTwo = new ArrayList<>(10000);
    
        public static class AccountSyncBad implements Runnable{
            synchronized void increase(){ //synchronized
                size++;
            }
    //        static synchronized void increase(){ //修改为static,这样即使两个线程指向不同的Runnable,但请求的是当前类的锁,因此可以正确同步
    //            size++;
    //        }
            @Override
            public void run() {
                int length = arrayOne.size();
                for (int i = 0; i < length; i++) {
                    if (arrayOne.get(i).intValue()==0){
                        increase();
                    }
                }
            }
        }
        public static void main(String[] args) throws InterruptedException{
            for (int i = 0; i < 10000; i++) {
                arrayOne.add(0);
                arrayTwo.add(0);
            }
            Thread threadOne = new Thread(new AccountSyncBad());
            Thread threadTwo = new Thread(new AccountSyncBad());
            threadOne.start();
            threadTwo.start();
            threadOne.join();
            threadTwo.join();
            System.out.println(size);
        }
    }
    
  • 相关阅读:
    安装 Panda3D 并使用原有的Python
    Jupyter Notebook PDF输出的中文支持
    lua的文件管理
    elasticsearch-hadoop.jar, 适用于spark3,hadoop3
    shell中递归遍历指定文件夹下的文件
    JDBC的ResultSet游标转spark的DataFrame,数据类型的映射以TeraData数据库为例
    Pandas一些小技巧
    用c++后缀自动机实现最大公共字符串算法,并封装成Python库
    后缀自动机的python实现
    PYTHON调用C接口(基于Ctypes)实现stein算法最大公约数的计算
  • 原文地址:https://www.cnblogs.com/fly-book/p/11384270.html
Copyright © 2020-2023  润新知