• 《Java 7 并发编程指南》学习概要 (2)Lock


    1、ReentrantLock

    (1)、lock()、unlock()一对方法与synchronized 意思一样,unlock()方法 要在finally里面释放。

    (2)、tryLock()方法:如果一 个线程调用这个方法不能获取Lock接口的控制权时,将会立即返回并且不会使这个线程进入睡眠。这个方法返回一个boolean值,true表示这个线程 获取了锁的控制权,false则表示没有。

    (3)、还有lockInterruptibly()、tryLock(long time, TimeUnit unit) 等方法。

    public class PrintQueue {
    
    
        private final Lock lock = new ReentrantLock();
    
    
        public void printJob(Object obj) {
            while (true) {
                if (lock.tryLock()) {
                    try {
                        System.out.printf("%s: Going to print a document
    ", Thread.
                                currentThread().getName());
                        Thread.sleep((long) (Math.random() * 2000));
                        System.out.println(Thread.currentThread().getName()
                                + ":  " + obj);
                        System.out.printf("%s: The document has been printed
    ",
                                Thread.currentThread().getName());
                        break;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        lock.unlock();
                    }
                }
                try {
                    Thread.sleep((long) (Math.random() * 2000));
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }
    
    
        public static void main(String[] args) {
            PrintQueue printQueue = new PrintQueue();
            Thread thread[] = new Thread[10];
            for (int i = 0; i < 10; i++) {
                thread[i] = new Thread(new Job(printQueue), "Thread " + i);
            }
            for (int i = 0; i < 10; i++) {
                thread[i].start();
            }
    
    
        }
    }
    
    
    class Job implements Runnable {
    
    
        private PrintQueue printQueue;
    
    
        public Job(PrintQueue printQueue) {
            this.printQueue = printQueue;
        }
    
    
        @Override
        public void run() {
            printQueue.printJob(new Object());
        }
    }
    


    输出:

    Thread 0: Going to print a document
    Thread 0:  java.lang.Object@1d4cee08
    Thread 0: The document has been printed
    Thread 5: Going to print a document
    Thread 5:  java.lang.Object@259f5e3f
    Thread 5: The document has been printed
    Thread 3: Going to print a document
    Thread 3:  java.lang.Object@1e48d65
    Thread 3: The document has been printed
    Thread 8: Going to print a document
    Thread 8:  java.lang.Object@12dfbabd
    Thread 8: The document has been printed
    Thread 2: Going to print a document
    Thread 2:  java.lang.Object@1e5cd7f9
    Thread 2: The document has been printed
    Thread 9: Going to print a document
    Thread 9:  java.lang.Object@61672c01
    Thread 9: The document has been printed
    Thread 1: Going to print a document
    Thread 1:  java.lang.Object@3c7a279c
    Thread 1: The document has been printed
    Thread 4: Going to print a document
    Thread 4:  java.lang.Object@77be91c8
    Thread 4: The document has been printed
    Thread 6: Going to print a document
    Thread 6:  java.lang.Object@551ee3
    Thread 6: The document has been printed
    Thread 7: Going to print a document
    Thread 7:  java.lang.Object@545ec940
    Thread 7: The document has been printed
    BUILD SUCCESSFUL (total time: 16 seconds)


    2、ReadWriteLock 

    ReentrantReadWriteLock 提供两把锁,一把用于读操作和一把用于写操作。同时可以有多个线程执行读操作,但只有一个线程可以执行写操作。当一个线程正在执行一个写操作,不可能有任何线程执行读操作。

    public class MyReadWriteLockTest {
    
        private double value1;
        private double value2;
        private ReadWriteLock lock;
    
        public MyReadWriteLockTest() {
            value1 = 1.0;
            value2 = 2.0;
            lock = new ReentrantReadWriteLock();
        }
    
        public double getValue1() {
            lock.readLock().lock();
            try {
                double value = value1;
                return value;
            } finally {
                lock.readLock().unlock();
            }
    
        }
    
        public double getValue2() {
            lock.readLock().lock();
            try {
                double value = value2;
                return value;
            } finally {
                lock.readLock().unlock();
            }
    
        }
    
        public void setValues(double value1, double value2) {
            lock.writeLock().lock();
            try {
                this.value1 = value1;
                this.value2 = value2;
            } finally {
                lock.writeLock().unlock();
            }
        }
    }


    3、修改Lock的公平性

    ReentrantLock类和 ReentrantReadWriteLock ,默认参数fair为false,即是不公平的:当有多个线程正在等待一把锁,这个锁必须选择它们中间的一个来获得进入临界区,选择任意一个是没有任何标准的

    设置fair为true值将开启公平模式:当有多个线程正在等待一把锁,这个锁必须选择它们中间的一个来获得进入临界区,它将选择等待时间最长的线程

    private Lock queueLock=new ReentrantLock(true);
    
    private ReadWriteLock queueLock=new ReentrantReadWriteLock(true);


    4、Lock中使用多个Condition

    await()、signal()、signalAll() 分别对应 wait()、notify()、notifyAll().

    class MyCollection {
    
        private String[] array;
        private int maxSize;
        private int count;
        private ReentrantLock lock;
        private Condition condition1;
        private Condition condition2;
    
        public MyCollection(int maxSize) {
            this.maxSize = maxSize;
            array = new String[maxSize];
            count = 0;
            lock = new ReentrantLock();
            condition1 = lock.newCondition();
            condition2 = lock.newCondition();
        } 
    
        public String get() {
            String line = null;
            lock.lock();
            try {
                while (count == 0) {
                    condition1.await();
                }
                line = array[count - 1];
                array[count - 1] = null;
                count--;
                condition2.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
            return line;
        }
        
            public void insert(String line) {
            lock.lock();
            try {
                while (count == maxSize) {
                    condition2.await();
                }
                array[count++] = line;
                condition1.signalAll();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }
    }
    
    class Producer implements Runnable {
    
        private MyCollection myCollection;
    
        public Producer(MyCollection myCollection) {
            this.myCollection = myCollection;
        }
    
        @Override
        public void run() {
            while (true) {
                String line = "String_" + System.currentTimeMillis();
                System.out.println(Thread.currentThread().getName() + ":" + line);
                myCollection.insert(line);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    class Consumer implements Runnable {
    
        private MyCollection myCollection;
    
        public Consumer(MyCollection myCollection) {
            this.myCollection = myCollection;
        }
    
        @Override
        public void run() {
            while (true) {
                String line = myCollection.get();
                System.out.println(Thread.currentThread().getName() + ":" + line);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }



  • 相关阅读:
    查看linux系统内置宏定义
    C++ typename 关键字总结
    vs2017 如何定位C++内存泄漏
    centos7.6下pyspider + python2.7安装
    centos7下安装python3.7.5
    centos7下docker安装
    centos7.6下redis安装
    centos7下git的安装
    centos7下mysql5.7的安装
    centos7下nginx,tomcaat开机启动(新)
  • 原文地址:https://www.cnblogs.com/leeeee/p/7276434.html
Copyright © 2020-2023  润新知