zoukankan      html  css  js  c++  java
  • 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);
        }
    }
    
  • 相关阅读:
    django 日志窜打问题
    获取f5 应用并发数情况返回JSON
    埋在 MySQL 数据库应用中的17个关键问题!
    python 模拟发送JSON数据
    python 模拟 curx -u
    分区表和全局索引
    Oracle 普通表转分区表
    阿里云吕漫漪:深度解析国内首个云原生数据库POLARDB的“王者荣耀”
    哪些顾虑会影响企业采用云桌面?
    哪些顾虑会影响企业采用云桌面?
  • 原文地址:https://www.cnblogs.com/fly-book/p/11384270.html
Copyright © 2011-2022 走看看