多线程之手撕多线程

手撕生产者消费者

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);
    }
}
全部评论

相关推荐

11-11 16:40
已编辑
门头沟学院 人工智能
不知道怎么取名字_:这个有点不合理了,相当于已经毕业了,但还是没转正,这不就是白嫖
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务