多线程打印ABC
三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串。
- 在
if (idx == num)
条件不满足时,锁会被释放,但线程会立即重新获取锁,导致忙等待(Busy Waiting),浪费CPU资源。
package Thread;
import java.util.concurrent.locks.ReentrantLock;
//三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串。
public class ABC {
public static int count = 12;
public static int idx = 0;
static ReentrantLock reentrantLock = new ReentrantLock();
public static void printABC(char c, int num){
for(int i = 1; i <= count;){
reentrantLock.lock();
if(idx == num){
idx = (idx + 1) % 3;
i ++;
System.out.print(c);
}
reentrantLock.unlock();
}
}
public static void main(String[] args){
Thread thread1 = new Thread(() -> printABC('A', 0));
Thread thread2 = new Thread(() -> printABC('B', 1));
Thread thread3 = new Thread(() -> printABC('C', 2));
thread1.start();
thread2.start();
thread3.start();
}
}
改进版,使用通知进行线程之间的交互。
package Thread;
import java.util.concurrent.locks.ReentrantLock;
//三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串。
public class ABC {
public static int count = 12;
public static int idx = 0;
static Object lock = new Object();//对象锁
public static void printABC(char c, int num){
for(int i = 1; i <= count; i ++){
synchronized (lock){
//被唤醒也不一定是自己该打印
while(idx != num){
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.print(c);
idx = (idx + 1) % 3;
lock.notifyAll();//唤醒等待的线程,不包括自己
}
}
}
public static void main(String[] args){
Thread thread1 = new Thread(() -> printABC('A', 0));
Thread thread2 = new Thread(() -> printABC('B', 1));
Thread thread3 = new Thread(() -> printABC('C', 2));
thread1.start();
thread2.start();
thread3.start();
}
}
两个线程交替奇偶打印1-100
package Thread;
public class EvenAndOdd {
public static int idx = 1;
static Object lock = new Object();
public static void printEven(boolean flag){
int c = flag ? 1 : 0;
while(true){
synchronized (lock){
while(idx % 2 != c){
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
if(idx > 100) return;
System.out.println(Thread.currentThread().getName() + " " + idx);
idx ++;
lock.notifyAll();
}
}
}
public static void main(String[] args){
Thread thread1 = new Thread(() -> printEven(true));
Thread thread2 = new Thread(() -> printEven(false));
thread1.setName("even");
thread2.setName("odd");
thread1.start();
thread2.start();
}
}
生产者-消费者
例如一个厨子10s生产一个,一个客人4s消费一个。
package Thread;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class CustomerAndProducer {
public static BlockingQueue<String> blockQueue = new ArrayBlockingQueue<>(100);
public static class Producer implements Runnable{
@Override
public void run() {
while(true){
try {
Thread.sleep(10000);
blockQueue.add("food");
System.out.println("厨师放了一个餐品");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static class Consumer implements Runnable{
@Override
public void run() {
while(true){
try {
Thread.sleep(4000);
String food = blockQueue.take();
System.out.println("消费者消费了一个餐品");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public static void main(String[] args){
Thread thread1 = new Thread(new Producer());
Thread thread2 = new Thread(new Consumer());
thread1.start();
thread2.start();
}
}
单例模式:懒汉,饿汉,双重校验锁
懒汉
package Singleton;
public class Singleton {
/*恶汉
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
*/
/*懒汉
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
}
*/
// 使用 volatile 关键字确保 instance 的可见性
private static volatile Singleton instance;
// 私有构造函数,防止外部实例化
private Singleton() {
// 初始化代码
}
// 获取单例实例的静态方法
public static Singleton getInstance() {
// 第一次检查,避免不必要的同步
if (instance == null) {
// 加锁,确保线程安全
synchronized (Singleton.class) {
// 第二次检查,防止多个线程同时通过第一次检查
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
随机数
有一个0-4的随机器rand4,如何实现0-6的随机器rand6,概率相同。拓展:rand X = func(rand Y),实现func函数