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

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

实现方式: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

 

posted on 2015-03-24 15:13  鳄鱼爸爸  阅读(420)  评论(0编辑  收藏  举报