-
- 1.1. 并发编程
- 1.1.1. Java实现阻塞队列
- 1.1.2. 手撕死锁
- 1.1.3. Java三个线程打印ABC
- 1.2. 设计模式
- 1.2.1. Java懒汉式双重检测锁?
- 1.2.2. Java懒汉式实现单例模式
- 1.2.3. 静态内部类实现单例模式
- 1.1. 并发编程
🤠Code-工程问题
1. Java工程
1.1. 并发编程
1.1.1. Java实现阻塞队列
一个full Condition和一个empty Condition
注意这两个队列的await()要用while包起来
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyArrayBlockingQueue {
int size = 50;
Lock lock = new ReentrantLock();
Condition empty = lock.newCondition();
Condition full = lock.newCondition();
Deque queue = new LinkedList();
void offer(Object object) {
lock.lock();
try {
while(queue.size() == size) {
empty.await();
}
queue.add(object);
full.signal();
} catch (Exception e) {
} finally {
lock.unlock();
}
}
Object poll() {
lock.lock();
try {
while(queue.isEmpty()) {
full.await();
}
Object res = queue.pollFirst();
empty.signal();
return res;
} catch(Exception e) {
return null;
} finally {
lock.unlock();
}
}
}
1.1.2. 手撕死锁
线程1需要获取锁1,然后获取锁2,需要等待线程2释放锁2
线程2需要获取锁2,然后获取锁1,需要等待线程1释放锁1
public class MyDeadLock {
Object resource1 = new Object();
Object resource2 = new Object();
public void deadLockTest() {
new Thread(() ->{
synchronized (resource1) {
System.out.println("get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("waiting for resource2");
synchronized(resource2) {
System.out.println("get resource2 success!");
}
}
}).start();
new Thread(() -> {
synchronized (resource2) {
System.out.println("get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("waiting for resource1");
synchronized(resource1) {
System.out.println("get resource1 success!");
}
}
}).start();
}
}
1.1.3. Java三个线程打印ABC
都有个await和notify,用于等待下一轮满足当前条件和唤醒下一个
synchronized和wait/notify实现
pre和cur都获取到锁才行(保证顺序性)
public class MyPrintABC {
public class PrintThread implements Runnable{
String name;
Object pre;
Object cur;
PrintThread(String name, Object pre, Object cur) {
this.name = name;
this.pre = pre;
this.cur = cur;
}
@Override
public void run() {
int count = 10;
while(count > 0) {
synchronized (pre) {
synchronized (cur) {
System.out.print(name);
count--;
cur.notifyAll();
}
try {
pre.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
public void printBySyn() {
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = new Object();
PrintThread printThread1 = new PrintThread("a", obj3, obj1);
PrintThread printThread2 = new PrintThread("b", obj1, obj2);
PrintThread printThread3 = new PrintThread("c", obj2, obj3);
new Thread(printThread1).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(printThread2).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(printThread3).start();
}
}
ReentrantLock和Condition实现
相比于synchronized保证顺序性用的cnt%3
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyPrintABCByLock {
int cnt = 0;
public void printABCByLock() {
Lock lock = new ReentrantLock();
Condition a = lock.newCondition();
Condition b = lock.newCondition();
Condition c = lock.newCondition();
new Thread(() -> {
try {
lock.lock();
for(int i = 0; i < 10; ++i) {
while(cnt % 3 != 0) {
try {
a.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print("a");
cnt++;
b.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(() -> {
try {
lock.lock();
for(int i = 0; i < 10; ++i) {
while(cnt % 3 != 1) {
try {
b.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print("b");
cnt++;
c.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(() -> {
try {
lock.lock();
for(int i = 0; i < 10; ++i) {
while(cnt % 3 != 2) {
try {
c.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print("c");
cnt++;
a.signal();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}).start();
}
}
1.2. 设计模式
1.2.1. Java懒汉式双重检测锁?
双重检查是因为可能会有指令重排序导致的创建多次(可能两个线程进入synchronized判读为null)
public class LazyDoubleCheckSingleton {
private LazyDoubleCheckSingleton(){};
private static volatile LazyDoubleCheckSingleton singleton;
private static LazyDoubleCheckSingleton getSingleton() {
if(singleton == null) {
synchronized (LazyDoubleCheckSingleton.class) {
if(singleton == null) {
singleton = new LazyDoubleCheckSingleton();
}
}
}
return singleton;
}
}
1.2.2. Java懒汉式实现单例模式
public class HungrySingleton {
private static HungrySingleton singleton = new HungrySingleton();
private HungrySingleton(){}
public static HungrySingleton getSingleton() {
return singleton;
}
}
1.2.3. 静态内部类实现单例模式
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton(){}
private static class SingletonHolder{
private static final StaticInnerClassSingleton singleton = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.singleton;
}
}