Lock

public class Outputter {
    
    private Lock lock = new ReentrantLock();
    public void output(String name){
        lock.lock();    //得到锁
        try{
            for(int i = 0; i < name.length();i++){
                System.out.print(name.charAt(i));
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            lock.unlock();    //释放锁
        }
    }
    

}
public class LockTest {

    public static void main(String[] args) {
        final Outputter outputter = new Outputter();
        new Thread(){
            public void run(){
                outputter.output("Chinaese ");
            }
        }.start();
        new Thread(){
            public void run(){
                outputter.output("Chinaese ");
            }
        }.start();
        new Thread(){
            public void run(){
                outputter.output("Chinaese ");
            }
        }.start();
    }
    
}

上述代码可以解决线程安全问题,效果和synchronized一样。不同的是,synchronized修饰的方法或者代码块执行完后自动释放锁,而lock需要手动释放锁。

对于数据区的内容,我们要做到  读写互斥  写写互斥 读读不互斥(这里先考虑读读互斥)

/**
 * 显然不满足我们的需求
 * 我们需要实现的是:读写互斥   写写互斥  读读不互斥
 * @author hp
 *
 */
public class ReadWriteLockTest {

    public static void main(String[] args) {
        final Data data = new Data();
        for(int i = 0;i<3;i++){
            new Thread(new Runnable(){
                public void run() {
                    for(int i = 0; i< 5;i++){
                        data.set(new Random().nextInt(30));
                    }
                }
            }).start();
        }
        
        for(int i = 0;i  < 3;i++){
            new Thread(new Runnable(){
                public void run() {
                    for(int i = 0;i< 5;i++){
                        data.get();
                    }
                }
            }).start();
        }
    }
    
    /*static class Data{
        private int data;
        
        public void set(int data){
            System.out.println(Thread.currentThread().getName()+"准备写数据");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.data = data;
            System.out.println(Thread.currentThread().getName()+"写入数据"+data);
        }
        
        public void get(){
            System.out.println(Thread.currentThread().getName()+"准备读取数据");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"读取"+this.data);
        }
        
    }*/
    
    
    static class Data{
        private int data;
        private ReadWriteLock rwl = new ReentrantReadWriteLock();
        public void set(int data){
            rwl.writeLock().lock();
            try {
                System.out.println(Thread.currentThread().getName()+"准备写数据");
                Thread.sleep(20);
                this.data = data;
                System.out.println(Thread.currentThread().getName()+"写入数据"+data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                rwl.writeLock().unlock();
            }
        }
        
        public void get(){
            rwl.readLock().lock();
            try {
                System.out.println(Thread.currentThread().getName()+"准备读取数据");
                Thread.sleep(20);
                System.out.println(Thread.currentThread().getName()+"读取"+this.data);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally{
                rwl.readLock().unlock();
            }
        }
        
    }
    
}
原文地址:https://www.cnblogs.com/lfdingye/p/7444504.html