写一个DCL 双重检查加锁(double-checked locking)java写一个阻塞队列
ReentrantLock ?Condition ?什么是 await()/ signal() 和wait() / nofity()?区别? 顺序打印线程abc
写一个DCL 双重检查加锁(double-checked locking)1,使用 volatile 防止指令重排序,(jmm加载顺序)
2,第一次判断当前对象是否为空
3,如果为空加synchronized
4.再检查一遍对象等于空 创建对象,因为此时如果有2个线程都在sync等待,如果不检查1线程创建后2线程还会进入再创建一次,这样就不是单例了。
package com.lisongtao.juc.a_juc;
import java.util.Arrays;
public class Singleton {
private static volatile Singleton singleton = new Singleton();
private Singleton() {
System.out.println("进入");
}
private static Singleton getSingleton(){
if(singleton==null){
synchronized (Singleton.class){
if(singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
public static void main(String[] args) {
Thread[] ths = new Thread[2000];
for(int i=0; i{
System.out.println(Singleton.getSingleton());
});
}
Arrays.asList(ths).forEach(o->o.start());
}
}
}
java写一个阻塞队列
1,先创建 ReentrantLock
2, 通过ReentrantLock实例出 Condition
3,实例化 Queue 用于存储
await()/ signal() 和 锁定机制Lock直接挂钩 。通过在Lock对象上调用newCondition()方法,将条件变量和一个锁对象进行绑定,进而控制并发程序访问竞争资源的安全。
package com.lisongtao.juc.a_juc; import java.util.Arrays; import java.util.linkedList; import java.util.Queue; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public class ProviderConsumer{ ReentrantLock lock = new ReentrantLock(); Condition pCondition = lock.newCondition(); Condition cConditon = lock.newCondition(); private int length; private Queue queue; public ProviderConsumer(int length) { this.length = length; this.queue = new linkedList (); } public void provide(T product) { lock.lock(); try { while (queue.size() >= length) { pCondition.await(); } queue.add(product); cConditon.signal(); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } public T consume() { lock.lock(); try { while (queue.isEmpty()) { cConditon.await(); } T product = queue.remove(); pCondition.signal(); return product; } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } return null; } public static void main(String[] args) { ProviderConsumer p = new ProviderConsumer(3); Thread[] thread = new Thread[10]; Thread[] thread2 = new Thread[5]; for (int i=0; i { p.provide(finalI); }); } for (int i=0; i { Object consume = p.consume(); System.out.println(consume.toString()); }); } Arrays.asList(thread).forEach(o->o.start()); Arrays.asList(thread2).forEach(o->o.start()); } }
顺序打印线程abc
1,先创建三个 线程类 分别打印ABC 实现 Runnable接口
2,定义一个count值用于计算打印顺序, count% 3 得到的取余值按照大小 调用 conditionB.signal(); 如果与对应的值不相等,进入等待,直到相等的出现再进行打印。
package com.lisongtao.juc.a_juc;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class PrintABC {
// volatile int value = 0;
private AtomicInteger value = new AtomicInteger(0);
ReentrantLock lock = new ReentrantLock();
Condition conditionA = lock.newCondition();
Condition conditionB = lock.newCondition();
Condition conditionC = lock.newCondition();
//打印多少遍
private int count;
public PrintABC(int count) {
this.count = count;
}
private void PrintABC() {
new Thread(new ThreadA()).start();
new Thread(new ThreadB()).start();
new Thread(new ThreadC()).start();
}
class ThreadA implements Runnable {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
if (value.get() % 3 != 0) {
conditionA.await();
}
System.out.print("A");
conditionB.signal();
value.getAndIncrement();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class ThreadB implements Runnable {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
if (value.get() % 3 != 1) {
conditionB.await();
}
System.out.print("B");
conditionC.signal();
value.getAndIncrement();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class ThreadC implements Runnable {
@Override
public void run() {
lock.lock();
try {
for (int i = 0; i < count; i++) {
if (value.get() % 3 != 2) {
conditionC.await();
}
System.out.println("C");
conditionA.signal();
value.getAndIncrement();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
PrintABC printABC = new PrintABC(5);
printABC.PrintABC();
}
}



