Java并发之JDK并发包(1)

实战Java高并发程序设计笔记


多线程的团队协作:同步控制

  1. synchronied的功能扩展:重入锁
  • 简单使用,与synchronied相比,重入锁有着显示的操作过程,必须手动指定何时加锁何时释放锁。对逻辑的控制的灵活性远远要比synchronied要好,在退出临界区是必须释放锁,否则其他线程无法访问该资源而堵塞。
public static void main(String args[]) throws InterruptedException {
        Runnable run = new MyRun();
        Thread thread1 = new Thread(run, "thread 1");
        Thread thread2 = new Thread(run, "thread 2");
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();
    }
    static class MyRun implements Runnable {
        private static final ReentrantLock lock = new ReentrantLock();
        private static int count = 0;
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                lock.lock();
                try {
                    count++;
                    System.out.println(Thread.currentThread().getName() + " i " + count);
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
  1. 中断响应
  • 对于synchronied来说,线程程在等待锁要么所得锁继续执行要么保持等待。而重入锁可以随时释放掉已获取锁的线程的锁。可用于解决死锁。以下代码如果将 thread1.interrupt(); 这行代码注释掉,则代码无法执行完成。
public static void main(String arg[]) {
        IntLock lock1 = new IntLock(1);
        IntLock lock2 = new IntLock(2);
        Thread thread1 = new Thread(lock1, "thread 1");
        Thread thread2 = new Thread(lock2, "thread 2");
        thread1.start();
        thread2.start();
        thread1.interrupt();
    }
    static class IntLock implements Runnable {
        int i; //控制加锁顺序
        private static final ReentrantLock lock1 = new ReentrantLock();
        private static final ReentrantLock lock2 = new ReentrantLock();
        public IntLock(int i) {
            this.i = i;
        }
        @Override
        public void run() {
            try {
                if (i == 1) {
                    System.out.println("lock 1");
                    lock1.lockInterruptibly();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        System.out.println(Thread.currentThread().getName() + e);
                    }
                    lock2.lockInterruptibly();
                } else {
                    System.out.println("lock 2");
                    lock2.lockInterruptibly();
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        System.out.println(Thread.currentThread().getName() + e);
                    }
                    lock1.lockInterruptibly();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                if (lock1.isHeldByCurrentThread()) {//判断当前线程是否持有锁
                    lock1.unlock();
                }
                if (lock2.isHeldByCurrentThread()) {
                    lock2.unlock();
                }
                System.out.println(Thread.currentThread().getName() + " 退出 ");
            }
        }
    }
  1. 锁申请等待时间
  • tryLock() :线程尝试获取锁,如果锁并未被其他线程占用,返回true,否则返回false
  • tryLock(long timeout, TimeUnit unit) :long timeout 表示时长,TimeUnit unit表示时长的单位,线程尝试获取锁,如果在指定timeout时间内没有获取到锁,则立即返回fase,否则返回true
public boolean tryLock()
public boolean tryLock(long timeout, TimeUnit unit)//long timeout 表示时长,TimeUnit unit表示时长的单位,线程尝试获取锁,如果在指定timeout时间内没有获取到锁,则立即返回fase,否则返回true
  1. 公平锁
  • 非公平锁:随机冲等待队列中挑选一个
  • 公平锁:特点不会产生饥饿现象,先请求锁的线程先获取锁,(FIFO先入先出)
public ReentrantLock()非公平锁
public ReentrantLock(boolean fair)//传true 则表示申明公平锁,否则申明非公平锁
  1. 重入锁的好搭档:Condition 条件
  • Condition的作用跟Object.wait和Object.notify类似,Condition借口提供部分如下基本方法
 public interface Condition {
    void await()
    void awaitUninterruptibly();
    long awaitNanos(long nanosTimeout) 
    boolean await(long time, TimeUnit unit)
    boolean awaitUntil(Date deadline) 
    void signal();
    void signalAll();
}
  • await使当前线程等待,同时释放当前锁,其他线程调用signal或者signalAll,线程会重新获得锁并继续执行。或者当前线程被中断,也能跳出等待
  • awaitUninterruptibly与await相同,但是不会响应中断
  • signal 随机唤醒一个等待中的线程
  • signalAll 唤醒所有等待中的线程
  1. 允许多个线程同事访问:信号量(Semaphore)
  • 信号量可指定多个线程同事访问一个资源
public Semaphore(int permits)
public Semaphore(int permits, boolean fair)//第二个参数可以指定是否公平
public void acquire()//尝试获得一个准入的许可
public void acquireUninterruptibly() 
public boolean tryAcquire()
public boolean tryAcquire(long timeout, TimeUnit unit)
public void release() 

acquire() :尝试获得一个准入的许可,无法获得,线程就会等待,直到有线程释放一个许可或者当前线程被中断。
acquireUninterruptibly():与acquire()方法相似,当时不响应中断。
tryAcquire():尝试回去一个许可,成功返回true,否则返回false
tryAcquire(long timeout, TimeUnit unit):在一段时间内如果获得了许可返回true否则返回false
release():释放一个许可

  1. ReadWriteLock 读写锁
  • 读读之间不阻塞
  • 读阻塞写,写也会阻塞读
  • 写写阻塞
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容

  • 摘要: 我们已经知道,synchronized 是Java的关键字,是Java的内置特性,在JVM层面实现了对临界...
    kingZXY2009阅读 1,829评论 0 20
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,952评论 1 18
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,598评论 18 399
  • 一、并发 进程:每个进程都拥有自己的一套变量 线程:线程之间共享数据 1.线程 Java中为多线程任务提供了很多的...
    SeanMa阅读 2,416评论 0 11
  • 对于种种的人生迹象来说,可以总结为:人是一个高智商却没开发的一个高等动物。没有一个人是笨的,也没有一个人是好的。 ...
    YOmen阅读 194评论 0 3