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();public void m1() {
try {
lock.lock();//synchronized(this)类似,锁定的是堆的对象
for (int i = 0; i < 10; i++)
System.out.println("m1-" + i);
} catch (Exception e) {
System.out.println("m1启动");} finally {
System.out.println("m1结束");
lock.unlock();
}
}public void m2() {
try {
lock.lock();
for (int i = 0; i < 10; i++)
System.out.println("m2-" + i);} catch (Exception e) {
System.out.println("m2启动");} finally {
System.out.println("m2结束");
lock.unlock();
}
}public static void main(String[] args) {
ReentrantLock1 reentrantLock1 = new ReentrantLock1();
new Thread(() -> reentrantLock1.m1()).start();
new Thread(() -> 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();public void m1() {
lock.lock();// 一直锁着,不手动释放, 和synchronized(this)类似,锁定的是堆的对象
}public void m2() {
boolean isNotLock = lock.tryLock();// 如果别的进程锁着就返回false,如果没锁返回true
// 我们可以根据有没有锁来执行自己的逻辑,而不需要等着锁的释放,更加灵活
if (isNotLock) {
System.out.println("lock对象没有被锁定");
} else {
System.out.println("lock对象被锁定了");
}
}public static void main(String[] args) {
ReentrantLock2 reentrantLock2 = new ReentrantLock2();
new Thread(() -> reentrantLock2.m1()).start();
new Thread(() -> 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();public void m1() {
lock.lock();
try {
System.out.println("t1 start");
while (true) {
}
} finally {
lock.unlock();
System.out.println("t1 end");
}
}public void m2() {
try {
lock.lockInterruptibly();
System.out.println("t2 start");
} catch (InterruptedException e) {
System.out.println("t2被打断了");
} finally {
if (lock.tryLock())
lock.unlock();
System.out.println("t2 end");
}
}public static void main(String[] args) {
ReentrantLock3 reentrantLock3 = new ReentrantLock3();
Thread t1 = new Thread(() -> reentrantLock3.m1(), "t1");
t1.start();
Thread t2 = new Thread(() -> reentrantLock3.m2(), "t2");
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);public void m1() {
for (int i = 0; i < 10; i++) {
try {
lock.lock();
System.out.println(Thread.currentThread().getName() + "running");
} finally {
lock.unlock();
}
}
}public static void main(String[] args) {
ReentrantLock4 lock4 = new ReentrantLock4();
new Thread(()->lock4.m1(),"t1").start();
new Thread(()->lock4.m1(),"t2").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;public synchronized void put(Integer i) {
while (lists.size() == MAX) { // wait大多数情况和while一起用
try {
this.wait();// 如果满了我就释放锁,并且等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lists.add(i);// 生产一个
count++;
this.notifyAll();// 叫醒消费者可以消费啦
}public synchronized Integer get() {
while (lists.size() == 0) {
try {
this.wait();// 如果集合为空,不能消费,释放锁,等着
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer num = lists.removeFirst();
count--;
this.notifyAll();// 叫醒生产者,可以继续生产啦
return 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;private Lock lock = new ReentrantLock();
private Condition p = lock.newCondition();// 生产者
private Condition c = lock.newCondition();// 消费者public void put(Integer i) {
try {
lock.lock();
while (lists.size() == MAX) {
try {
p.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lists.add(i);
count++;
c.signalAll();
} finally {
lock.unlock();
}
}public Integer get() {
Integer i = null;
try {
lock.lock();
while (lists.size() == 0) {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i = lists.removeFirst();
count++;
p.signalAll();
} finally {
lock.unlock();
}
return i;
}}
7.ThreadLocal 线程局部变量 每个线程中的这个变量归自己线程管
package com.dingyu;public class ThreadLocal1 {
private ThreadLocal<Integer> tl = new ThreadLocal<Integer>();public void m1() {
System.out.println(tl.get());
}public void m2() {
tl.set(7898);
}public static void main(String[] args) {
ThreadLocal1 local1 = new ThreadLocal1();
new Thread(() -> local1.m2()).start();try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}new Thread(() -> local1.m1()).start();
}
}


浙公网安备 33010602011771号