zoukankan      html  css  js  c++  java
  • 5,临界区 之 lock

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

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

    实现方式:synchronized 或 lock

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

    package com.zyguo.thread;
    
    import java.util.concurrent.locks.ReentrantLock;
    
    public class UserLock {
        private int money;
        private int id;
        private ReentrantLock lock = new ReentrantLock();
        
        public UserLock( int id ){
            this.setId(id);
        } 
        public int getMoney() {
            return money;
        }
        
        public int addMoney( int incrNum ){
            try {
                lock.lock();
                System.out.println("addMoney, lock=" + Thread.currentThread() + ",money=" + this.money );
                this.money = this.money + incrNum; 
                Thread.sleep( 3000 );
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally{
                lock.unlock();
                System.out.println("addMoney, unlock=" + Thread.currentThread() + ",money=" + this.money );
            }
            return this.money;
        }
        
        public 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_lock {
        public static void main(String[] args) {
            final UserLock u = new UserLock(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]
    addMoney, lock=Thread[test-thread-0,5,test-threadgroup],money=0
    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=WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    Thread[test-thread-0,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-1,5,test-threadgroup],state=WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    addMoney, lock=Thread[test-thread-1,5,test-threadgroup],money=1
    addMoney, unlock=Thread[test-thread-0,5,test-threadgroup],money=2
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-2,5,test-threadgroup],state=WAITING
    addMoney, unlock=Thread[test-thread-1,5,test-threadgroup],money=2
    addMoney, lock=Thread[test-thread-2,5,test-threadgroup],money=2
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,],state=TERMINATED
    Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
    Thread[test-thread-0,5,],state=TERMINATED
    Thread[test-thread-1,5,],state=TERMINATED
    Thread[test-thread-2,5,test-threadgroup],state=TIMED_WAITING
    addMoney, unlock=Thread[test-thread-2,5,test-threadgroup],money=3
  • 相关阅读:
    1.Oracle实例和Oracle数据库(Oracle体系结构)
    04.SQL基础-->分组与分组函数
    SYSAUX表空间满的解决方法
    Linux 软件安装到 /usr,/usr/local/ 还是 /opt 目录?
    Python学习-八周五次课(12月15日)
    ELK安装
    Python学习-八周二次课(12月12日)
    Python学习-八周一次课(12月11日)
    Python学习——七周四次课(12月7日)
    Python学习-复习7次课(12月4日)
  • 原文地址:https://www.cnblogs.com/zyguo/p/4362880.html
Copyright © 2011-2022 走看看