• 4,临界区 之 synchronized


    前提背景:多个并发线程共享同一个资源时,为防止这些共享资源可能出现的错误或数据不一致问题,提出了临界区的概念

    临界区: 指一个用以访问共享资源的代码块,这个代码块在同一时间内只能允许一个线程访问

    实现方式:synchronized 或 lock

    synchronized 方式如下, User 给addMoney方法加上了synchronized , 相当于加了锁,后面同时起了3个线程,都调这个方法,因为设置了sleep 3 秒,可以看到 会有2个线程处于 BLOCKED 的状态,直到释放

    package com.zyguo.thread;
    
    public class User {
        private int money;
        private int id;
        
        public User( int id ){
            this.setId(id);
        } 
        public int getMoney() {
            return money;
        }
        
        public synchronized int addMoney( int incrNum ){
            this.money = this.money + incrNum; 
            try {
                Thread.sleep( 3000 );
                System.out.println("addMoney, currThread=" + Thread.currentThread() );
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return this.money;
        }
        
        public synchronized int reducMoney( int reducNum ){
            this.money = this.money - reducNum;
            return this.money;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
    }
    package com.zyguo.thread;
    
    import java.util.ArrayList;
    
    
    public class Main_synchronized {
        public static void main(String[] args) {
            final User u = new User(1);
            int threadNum = 3;
            final ThreadGroup tgroup = new ThreadGroup("test-threadgroup");
            final ArrayList<Thread> tList = new ArrayList<>();
            //定义10个线程
            for( int i = 0; i < threadNum; i++ ){
                Thread t = new Thread( tgroup, new Runnable() {
                    @Override
                    public void run() {
                        u.addMoney(1);
                    }
                } ,"test-thread-" + i);
                
                tList.add( t );
                t.start();
                System.out.println("start thread = " + t );
            }
    
            //监控线程的活动的子线程数
            Thread t = new Thread( new Runnable() {
                @Override
                public void run() {
                    int activeCount = tgroup.activeCount();
                    while ( activeCount > 0 ) {
                        for (Thread thread : tList) {
                            System.out.println( thread + ",state=" + thread.getState() );
                        }
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        activeCount = tgroup.activeCount();
                    }
                }
            });
            
            t.start();
            
        }
        
    }

    结果如下

    start thread = Thread[test-thread-0,5,test-threadgroup]
    start thread = Thread[test-thread-1,5,test-threadgroup]
    start thread = Thread[test-thread-2,5,test-threadgroup]
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=BLOCKED
    addMoney, currThread=Thread[test-thread-0,5,test-threadgroup]
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=BLOCKED
    Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
    addMoney, currThread=Thread[test-thread-2,5,test-threadgroup]
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,],state=TERMINATED
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,],state=TERMINATED
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,],state=TERMINATED
    addMoney, currThread=Thread[test-thread-1,5,test-threadgroup]

     

  • 相关阅读:
    Linux中创建Daemon进程的三种方法【转】
    Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例【转】
    使用 Qemu 虚拟 ARM64 平台演示 kdump 崩溃转存【转】
    自旋锁 spin_lock、 spin_lock_irq 以及 spin_lock_irqsave 的区别【转】
    Linux中的spinlock机制[四]
    Linux中的虚拟内存机制和内存映射【转】
    那些情况该使用它们spin_lock到spin_lock_irqsave【转】
    Linux内核中的软中断、tasklet和工作队列详解【转】
    Linux 读写memory操作,devmem直接访问物理内存地址【转】
    Linux性能之DVFS/cpufreq【转】
  • 原文地址:https://www.cnblogs.com/zyguo/p/4347021.html
Copyright © 2020-2023  润新知