多线程实现
Java中的Thread类就是专门用来创建线程和操作线程的类。
创建线程的两种方法
1.继承 Thread 类并重写它的run()
方法,然后用这个子类来创建对象并调用start()
方法。
2.当一个线程已经继承了另一个类时,可以通过实现Runnable接口来构造。
ThreadLocal
ThreadLocal提供了线程局部变量,每个线程可以通过set()、get()操作这个局部变量,但填充的变量属于当前线程,对其他线程来说是隔离的。如果不使用ThreadLocal,通过同一个对象创建的线程就会将对象中的变量当作共享变量,这是线程不安全的。
线程同步
例题:创建三个线程,按顺序连续输出三次A、B、C三个字符。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
private static ReentrantLock lock = new ReentrantLock();
private static int count = 0;
private static Condition condition = lock.newCondition();
public static void main(String[] args) {
Thread A = new Thread(() -> {
//加锁 一次只有一个线程输出
lock.lock();
try {
while (true) {
//因为只循环3次 所以到9的时候就结束循环
if (count == 9) {
break;
}
//当余数为0 就输出A
if (count % 3 == 0) {
count++;
System.out.println("A");
//唤醒其他等待线程
condition.signalAll();
} else {
try {
//等待
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
lock.unlock();
}
});
Thread B = new Thread(() -> {
lock.lock();
try {
while (true) {
if (count == 9) {
break;
}
if (count % 3 == 1) {
count++;
System.out.println("B");
condition.signalAll();
} else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
lock.unlock();
}
});
Thread C = new Thread(() -> {
lock.lock();
try {
while (true) {
if (count == 9) {
break;
}
if (count % 3 == 2) {
count++;
System.out.println("C");
condition.signalAll();
} else {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} finally {
lock.unlock();
}
});
A.start();
B.start();
C.start();
}
}
生产者消费者模式
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;
public class PCModel {
//阻塞队列
private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
public static void main(String[] args) {
//生产者
Thread provider = new Thread(() -> {
Random random = new Random();
for (int j = 0; j < 5; j++) {
try {
int i = random.nextInt();
//注释直到插入数据
queue.put(i);
System.out.println("生产数据:" + i);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//消费者
Thread consumer = new Thread(() -> {
Integer data;
for (int i = 0; i < 5; i++) {
try {
//阻塞直到取出数据
data = queue.take();
System.out.println("消费数据:" + data);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
//启动线程
provider.start();
consumer.start();
}
}