多线程之手撕多线程
手撕生产者消费者
public class ProducerAndConsumer1 {
private final int MAX_LEN = 10;
private Queue<Integer> queue = new LinkedList<Integer>();
class Producer extends Thread {
@Override
public void run() {
while(true) {
synchronized (queue) {
while (queue.size() == MAX_LEN) {
queue.notify();//满了后尝试唤醒m某个线程
System.out.println("当前队列满");
//当有多个生产者时,可能会打印多次,唤醒的还是生产者
try {
queue.wait();//满了,当前线程应该进入等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.add(1);
queue.notifyAll();
System.out.println("生产者生产一条任务,当前队列长度为"+queue.size());
try {
Thread.sleep(500);//这个只是为了让屏幕打印的慢一点。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
class Consumer extends Thread {
@Override
public void run() {
while (true) {
synchronized (queue) {
while (queue.size() == 0) {
queue.notifyAll();
System.out.println("当前队列为空");
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
queue.poll();
queue.notifyAll();
System.out.println("消费者消费一条任务,当前队列长度为"+queue.size());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) {
ProducerAndConsumer1 pc = new ProducerAndConsumer1();
Producer producer1 = pc.new Producer();
Consumer consumer1 = pc.new Consumer();
Producer producer2 = pc.new Producer();
Consumer consumer2 = pc.new Consumer();
producer2.start();
consumer2.start();
producer1.start();
consumer1.start();
}
}阻塞队列的写法
main函数
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
public class Main {
public static void main(String [] args){
BlockingQueue<String> queue = new LinkedBlockingQueue<>(3);
//设置队列大小为2,默认是Integer.Max_value
Consume consume = new Consume(queue);
Product product = new Product(queue);
for(int i=0;i<5;i++){
new Thread(product).start();
new Thread(consume).start();
}
}
}生产者
import java.util.concurrent.BlockingQueue;
public class Product implements Runnable {
BlockingQueue<String> queue;
public Product(BlockingQueue<String> queue){
this.queue = queue;
}
@Override
public void run(){
try {
String temp = Thread.currentThread().getName()+"生产了产品";
System.out.println("线程"+Thread.currentThread().getName() +"在生产");
queue.put(temp);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}消费者
import java.util.concurrent.BlockingQueue;
public class Consume implements Runnable {
BlockingQueue<String> queue;
public Consume(BlockingQueue<String> queue){
this.queue = queue;
}
@Override
public void run(){
try {
String temp = queue.take();
System.out.println(temp+"被消费了,消费线程是:"+Thread.currentThread().getName());
}catch (InterruptedException e){
e.printStackTrace();
}
}
}运行结果
顺序打印奇偶数
public class Print2 implements Runnable {
int i = 1;
public static void main(String[] args) {
Print2 t = new Print2();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
public void run(){
while(true){
synchronized(this){
notify();
try{
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
if(i <= 100){
System.out.println(Thread.currentThread().getName()+ ":" +i);
i++;
try{
wait();
}catch (InterruptedException e ){
e.printStackTrace();
}
}
}
}
}
}顺序打印ABC
public class Print3 {
public static class ThreadPrinter implements Runnable {
private String name;
private Object prev;
private Object self;
private ThreadPrinter(String name, Object prev, Object self) {
this.name = name;
this.prev = prev;
this.self = self;
}
@Override
public void run() {
int count = 20;
while (count > 0) {// 多线程并发,不能用if,必须使用whil循环
synchronized (prev) { // 先获取 prev 锁
synchronized (self) {// 再获取 self 锁
System.out.println(Thread.currentThread().getName()+":"+name);
count--;
self.notifyAll();
// 唤醒其他线程竞争self锁,注意此时self锁并未立即释放。
}
// 此时执行完self的同步块,self锁才释放。要不也可以用wait方法,释放锁
try {
if (count == 0) {
// 如果count==0,表示这是最后一次打印操作,通过notifyAll操作释放对象锁。
prev.notifyAll();
} else {
prev.wait(); // 立即释放 prev锁,当前线程休眠,等待唤醒
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public static void main(String[] args) throws Exception {
Object a = new Object();
Object b = new Object();
Object c = new Object();
ThreadPrinter pa = new ThreadPrinter("A", c, a);
ThreadPrinter pb = new ThreadPrinter("B", a, b);
ThreadPrinter pc = new ThreadPrinter("C", b, c);
new Thread(pa).start();
Thread.sleep(100);// 保证初始ABC的启动顺序
new Thread(pb).start();
Thread.sleep(100);
new Thread(pc).start();
Thread.sleep(100);
}
}

