多线程实战篇

并发是结构,并行是执行 __go 语言之父。

img

一般来说,我们希望我们的系统的结构是松散耦合的,比如,A线程向B线程发送消息,用什么方式去告诉线程B是合理的呢?在小区里,物业需要知道业主的意见,设立了一个意见箱,那么业主就不用去找物业,物业的人员也是变动的。直接找工作人员不是一件方便的事。投递意见箱就不用管工作人员的变动。

知识点

  1. 锁与信号量
  2. 线程状态的切换
  3. 线程池
  4. 锁-sync
  5. 锁-Lock
  6. 锁的分类
  7. 临界区-阻塞-活锁-死锁
  8. JMM 多线程模型

JUC包

  1. Blocking Queue
    Blocking Queue 适合做数据共享的通道,主要是在Blocking上。以ArrayBlockingQueue为例:
    当入队列时,队列满了,offer() 返回false, put()会一直等待直到队列有空闲的位置。
    反之,当队列为空时,poLl() 返回空,take()会直接等待,直到队列有元素。
    以下是一个Java代码示例,演示了ArrayBlockingQueue的阻塞行为以及线程之间的通知和唤醒机制。这个示例中,我将创建两个线程:一个生产者(Producer)和一个消费者(Consumer)。生产者将尝试向队列中放入元素,而消费者将尝试从队列中取出元素。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueueExample {
    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

        // 生产者线程
        Thread producer = new Thread(() -> {
            try {
                int value = 0;
                while (true) {
                    System.out.println("生产者准备生产:" + value);
                    queue.put(value);
                    System.out.println("生产者生产了:" + value);
                    value++;
                    Thread.sleep(100); // 模拟耗时的生产过程
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    Integer value = queue.take();
                    System.out.println("消费者消费了:" + value);
                    Thread.sleep(1000); // 模拟耗时的消费过程
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 启动生产者和消费者线程
        producer.start();
        consumer.start();
    }
}

在这个例子中,我使用了put()方法和take()方法,它们分别用于在队列满时阻塞生产者线程和在队列空时阻塞消费者线程。

1.生产者每生产一个元素就将其放入队列中。如果队列已满,则生产者线程会阻塞,直到队列中有空闲的空间。
2.消费者从队列中取出一个元素并消费它。如果队列为空,则消费者线程会阻塞,直到队列中有新的元素。

这个过程演示了ArrayBlockingQueue的阻塞行为,以及它如何在多线程环境中用于线程间的协作。在运行上述代码时,请注意,程序将无限循环运行,因为我没有添加用于停止线程的逻辑。生产者和消费者将不断地生产和消费元素。在实际应用中,你可能需要一些逻辑来优雅地停止这些线程,例如设置一个特定的条件来中断它们的循环。
此外,put()和take()方法是BlockingQueue接口中的关键方法,用于处理生产者-消费者问题中的同步问题,确保当队列满时生产者阻塞,队列空时消费者阻塞,这样就避免了资源的浪费和过度竞争。

  1. AQS (abstarct )
  2. ArrayBlockingQueue
  3. CountDownLatch
  4. CyclicBarrier
  5. Lock
  6. AtomicInteger
  7. readWriteLock
  8. stampedLock
  9. semaphore

资料准备

  1. 12个设计模式 Mutipart-threa-patarn
  2. https://www.kancloud.cn/hanxt/concurrency/2787349
  3. Java高并发核心编程卷2
  4. go 高级编程
posted @ 2023-11-13 23:34  庭有奇树  阅读(9)  评论(0编辑  收藏  举报