Java马士兵高并发编程视频学习笔记(二)

1.ReentrantLock的简单使用  

Reentrant n.再进入

ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)

可以完成synchronized相同的作用,但必须手动释放锁

复制代码
package com.dingyu2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**

  • Reentrant n.再进入
  • ReentrantLock 一个可重入互斥Lock具有与使用synchronized方法和语句访问的隐式监视锁相同的基本行为和语义,但具有扩展功能。(从jdk1.8中文版复制而来)
  • 可以完成synchronized相同的作用,但必须手动释放锁
  • @author dingyu

*/
public class ReentrantLock1 {
private Lock lock = new ReentrantLock();

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        lock.lock();//synchronized(this)类似,锁定的是堆的对象
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)
            System.out.println(</span>"m1-" +<span style="color: #000000;"> i);
    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
        System.out.println(</span>"m1启动"<span style="color: #000000;">);

    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        System.out.println(</span>"m1结束"<span style="color: #000000;">);
        lock.unlock();
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        lock.lock();
        </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">)
            System.out.println(</span>"m2-" +<span style="color: #000000;"> i);

    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) {
        System.out.println(</span>"m2启动"<span style="color: #000000;">);

    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        System.out.println(</span>"m2结束"<span style="color: #000000;">);
        lock.unlock();
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    ReentrantLock1 reentrantLock1 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReentrantLock1();
    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> reentrantLock1.m1()).start();
    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> reentrantLock1.m2()).start();
}

}

复制代码

2.ReentrantLock对synchronized的扩展之tryLock()

复制代码
package com.dingyu2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**

  • ReentrantLock对synchronized的扩展之tryLock()
  • @author dingyu

*/
public class ReentrantLock2 {
private Lock lock = new ReentrantLock();

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
    lock.lock();</span><span style="color: #008000;">//</span><span style="color: #008000;"> 一直锁着,不手动释放, 和synchronized(this)类似,锁定的是堆的对象</span>

}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
    </span><span style="color: #0000ff;">boolean</span> isNotLock = lock.tryLock();<span style="color: #008000;">//</span><span style="color: #008000;"> 如果别的进程锁着就返回false,如果没锁返回true
    </span><span style="color: #008000;">//</span><span style="color: #008000;"> 我们可以根据有没有锁来执行自己的逻辑,而不需要等着锁的释放,更加灵活</span>
    <span style="color: #0000ff;">if</span><span style="color: #000000;"> (isNotLock) {
        System.out.println(</span>"lock对象没有被锁定"<span style="color: #000000;">);
    } </span><span style="color: #0000ff;">else</span><span style="color: #000000;"> {
        System.out.println(</span>"lock对象被锁定了"<span style="color: #000000;">);
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    ReentrantLock2 reentrantLock2 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReentrantLock2();
    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> reentrantLock2.m1()).start();
    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> reentrantLock2.m2()).start();
}

}

复制代码

3.ReentranLock对synchronized的扩展:可以被另外的线程打断

复制代码
package com.dingyu2;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**

  • ReentranLock对synchronized的扩展:可以被另外的线程打断
  • 因为m1方法一直占着锁,m2永远不可能得到锁,既然得不到锁,我们就关闭m2好了,这时候得用lockInterruptibly
  • @author dingyu

*/
public class ReentrantLock3 {
private Lock lock = new ReentrantLock();

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
    lock.lock();
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        System.out.println(</span>"t1 start"<span style="color: #000000;">);
        </span><span style="color: #0000ff;">while</span> (<span style="color: #0000ff;">true</span><span style="color: #000000;">) {
        }
    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        lock.unlock();
        System.out.println(</span>"t1 end"<span style="color: #000000;">);
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        lock.lockInterruptibly();
        System.out.println(</span>"t2 start"<span style="color: #000000;">);
    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
        System.out.println(</span>"t2被打断了"<span style="color: #000000;">);
    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        </span><span style="color: #0000ff;">if</span><span style="color: #000000;"> (lock.tryLock())
            lock.unlock();
        System.out.println(</span>"t2 end"<span style="color: #000000;">);
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    ReentrantLock3 reentrantLock3 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReentrantLock3();
    Thread t1 </span>= <span style="color: #0000ff;">new</span> Thread(() -&gt; reentrantLock3.m1(), "t1"<span style="color: #000000;">);
    t1.start();
    Thread t2 </span>= <span style="color: #0000ff;">new</span> Thread(() -&gt; reentrantLock3.m2(), "t2"<span style="color: #000000;">);
    t2.start();
    t2.interrupt();
}

}

复制代码

4.ReentrantLock对synchronized的扩展 : 可以指定公平锁

复制代码
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**

  • ReentrantLock对synchronized的扩展 : 可以指定公平锁,哪个线程等待时间长,哪个先执行
  • 在构造函数中放入ture参数
  • @author dingyu

*/
public class ReentrantLock4 {
private Lock lock = new ReentrantLock(true);

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
    </span><span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; 10; i++<span style="color: #000000;">) {
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            lock.lock();
            System.out.println(Thread.currentThread().getName() </span>+ "running"<span style="color: #000000;">);
        } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
            lock.unlock();
        }
    }
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    ReentrantLock4 lock4 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReentrantLock4();
    </span><span style="color: #0000ff;">new</span> Thread(()-&gt;lock4.m1(),"t1"<span style="color: #000000;">).start();
    </span><span style="color: #0000ff;">new</span> Thread(()-&gt;lock4.m1(),"t2"<span style="color: #000000;">).start();
}

}

复制代码

5.使用wait和notifyAll实现消费者生产者模式

复制代码
package com.dingyu2;

import java.util.LinkedList;

/**

  • 使用wait和notifyAll实现消费者生产者模式
  • @author dingyu

*/
public class ProduceConsumer {
private final LinkedList<Integer> lists = new LinkedList<Integer>();
private final int MAX = 10;
private int count = 0;

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> put(Integer i) {
    </span><span style="color: #0000ff;">while</span> (lists.size() == MAX) { <span style="color: #008000;">//</span><span style="color: #008000;"> wait大多数情况和while一起用</span>
        <span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            </span><span style="color: #0000ff;">this</span>.wait();<span style="color: #008000;">//</span><span style="color: #008000;"> 如果满了我就释放锁,并且等待</span>
        } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
    }
    lists.add(i);</span><span style="color: #008000;">//</span><span style="color: #008000;"> 生产一个</span>
    count++<span style="color: #000000;">;
    </span><span style="color: #0000ff;">this</span>.notifyAll();<span style="color: #008000;">//</span><span style="color: #008000;"> 叫醒消费者可以消费啦</span>

}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">synchronized</span><span style="color: #000000;"> Integer get() {
    </span><span style="color: #0000ff;">while</span> (lists.size() == 0<span style="color: #000000;">) {
        </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
            </span><span style="color: #0000ff;">this</span>.wait();<span style="color: #008000;">//</span><span style="color: #008000;"> 如果集合为空,不能消费,释放锁,等着</span>
        } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
            e.printStackTrace();
        }
    }
    Integer num </span>=<span style="color: #000000;"> lists.removeFirst();
    count</span>--<span style="color: #000000;">;
    </span><span style="color: #0000ff;">this</span>.notifyAll();<span style="color: #008000;">//</span><span style="color: #008000;"> 叫醒生产者,可以继续生产啦</span>
    <span style="color: #0000ff;">return</span><span style="color: #000000;"> num;
}

}

复制代码

6.使用Condition 完成生产者消费者模式

复制代码
package com.dingyu2;
/**
 * 使用Condition 完成生产者消费者模式
 * @author dingyu
 *
 */

import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ProduceConsumer2 {
private final LinkedList<Integer> lists = new LinkedList<Integer>();
private final int MAX = 10;
private int count = 0;

</span><span style="color: #0000ff;">private</span> Lock lock = <span style="color: #0000ff;">new</span><span style="color: #000000;"> ReentrantLock();
</span><span style="color: #0000ff;">private</span> Condition p = lock.newCondition();<span style="color: #008000;">//</span><span style="color: #008000;"> 生产者</span>
<span style="color: #0000ff;">private</span> Condition c = lock.newCondition();<span style="color: #008000;">//</span><span style="color: #008000;"> 消费者</span>

<span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> put(Integer i) {
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        lock.lock();
        </span><span style="color: #0000ff;">while</span> (lists.size() ==<span style="color: #000000;"> MAX) {
            </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                p.await();
            } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
                e.printStackTrace();
            }
        }
        lists.add(i);
        count</span>++<span style="color: #000000;">;
        c.signalAll();
    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        lock.unlock();
    }
}

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> Integer get() {
    Integer i </span>= <span style="color: #0000ff;">null</span><span style="color: #000000;">;
    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        lock.lock();
        </span><span style="color: #0000ff;">while</span> (lists.size() == 0<span style="color: #000000;">) {
            </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
                c.await();
            } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
                e.printStackTrace();
            }
        }
        i </span>=<span style="color: #000000;"> lists.removeFirst();
        count</span>++<span style="color: #000000;">;
        p.signalAll();
    } </span><span style="color: #0000ff;">finally</span><span style="color: #000000;"> {
        lock.unlock();
    }
    </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> i;
}

}

复制代码

 7.ThreadLocal 线程局部变量  每个线程中的这个变量归自己线程管

复制代码
package com.dingyu;

public class ThreadLocal1 {
private ThreadLocal<Integer> tl = new ThreadLocal<Integer>();

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m1() {
    System.out.println(tl.get());
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> m2() {
    tl.set(</span>7898<span style="color: #000000;">);
}

</span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
    ThreadLocal1 local1 </span>= <span style="color: #0000ff;">new</span><span style="color: #000000;"> ThreadLocal1();
    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> local1.m2()).start();

    </span><span style="color: #0000ff;">try</span><span style="color: #000000;"> {
        Thread.sleep(</span>5000<span style="color: #000000;">);
    } </span><span style="color: #0000ff;">catch</span><span style="color: #000000;"> (InterruptedException e) {
        e.printStackTrace();
    }

    </span><span style="color: #0000ff;">new</span> Thread(() -&gt;<span style="color: #000000;"> local1.m1()).start();
}

}

复制代码

 

原文地址:https://www.cnblogs.com/dddyyy/p/9975838.html
posted @ 2019-06-08 21:10  星朝  阅读(395)  评论(0编辑  收藏  举报