zoukankan      html  css  js  c++  java
  • 并发编程002 --- 线程的基本使用

    线程状态

    1、OS层面

          初始状态----可运行状态-----运行状态-------阻塞状态-------终止状态

    2、java语言层面

          初始状态----运行状态-------等待状态------限时等待状态-------终止状态

          java语言层面,无法区分线程是可运行还是运行(OS层面的状态)

    基本使用 --- 创建、运行、休眠、让步

    1、创建

    继承Thread类,并重写run方法;实现Runnable接口类;创建后进入初始状态

    2、运行

    Thread类的start方法;进入运行态

    3、休眠

    sleep方法,进入阻塞态,线程休眠期间,任意线程可获得执行权,超时后,重新等待CPU调度。

    4、让步

    yield方法,只是让当前线程暂停,不会进入阻塞态,期间,只有相同优先级或者更高优先级的线程可获得执行权。

    从源码即可看出sleep和yield的区别,sleep会抛出InterruptedException异常,而yield不会。

    等待通知 --- wait、notify、notifyAll

    wait、notify和notifyAll方法并不是Thread类提供的方法,而是Object类提供的方法

    wait方法:使当前执行代码的线程进行等待,并且将该线程放入等待队列中,直到被其他线程通知执行,此时释放锁;

                     执行条件为:必须获取到该对象的对象级别的锁,而且wait方法必须在同步方法或者同步代码块中执行。

    notify方法:通知等待队列上的线程继续执行,执行条件和wait方法相同

    notifyAll方法:通知等待队列上的所有线程继续执行,执行条件和wait方法相同

    典型示例为生产者、消费者模式

    public class BlockingQ {
        private LinkedList<Integer> valueList = new LinkedList<>();
    
        private final Object lock = new Object();
    
        private static final int MAX_SIZE = 3;
    
        public void produce() {
            Integer value = new Random().nextInt();
    
            synchronized (lock) {
                while (this.valueList.size() >= MAX_SIZE) {
                    System.out.println("Thread " + Thread.currentThread().getName() + " produce wait.");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        System.out.println("Produce interrupted!!");
                    }
                }
    
                System.out.println("Thread " + Thread.currentThread().getName() + " produce value.");
                this.valueList.add(value);
                lock.notifyAll();
            }
        }
    
        public void consume() {
            synchronized (lock) {
                while (valueList.size() <= 0) {
                    System.out.println("Thread " + Thread.currentThread().getName() + " consume wait.");
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        System.out.println("Consume interrupted!!");
                    }
                }
    
                System.out.println("Thread " + Thread.currentThread().getName() + " consume value.");
                valueList.remove(0);
                lock.notifyAll();
            }
        }
    }

    生产者:

    public class Producer implements Runnable {
        private BlockingQ blockingQ;
    
        public Producer(BlockingQ blockingQ) {
            this.blockingQ = blockingQ;
        }
    
        @Override
        public void run() {
            blockingQ.produce();
        }
    }

    消费者:

    public class Consumer implements Runnable {
        private BlockingQ blockingQ;
    
        public Consumer(BlockingQ blockingQ) {
            this.blockingQ = blockingQ;
        }
    
        @Override
        public void run() {
            blockingQ.consume();
        }
    }

    执行方法:

    public class Main {
    
        public static void main(String[] args) {
    
            BlockingQ blockingQ = new BlockingQ();
    
            Producer producer = new Producer(blockingQ);
            Consumer consumer = new Consumer(blockingQ);
    
            // producer
            Thread thread1 = new Thread(producer);
            Thread thread2 = new Thread(producer);
            Thread thread3 = new Thread(producer);
            Thread thread4 = new Thread(producer);
    
            // consumer
            Thread thread5 = new Thread(consumer);
            Thread thread6 = new Thread(consumer);
            Thread thread7 = new Thread(consumer);
            Thread thread8 = new Thread(consumer);
    
            thread1.start();
            thread2.start();
            thread3.start();
            thread4.start();
            thread5.start();
            thread6.start();
            thread7.start();
            thread8.start();
        }
    }

    执行结果:

  • 相关阅读:
    【手绘漫画】图解LeetCode之x 的平方根(LeetCode 69题)
    tcp 发送长度9 实际组包49
    tcp 发送报文长度和响应报文长度
    http 响应报文
    中台翻车纪实:一年叫停,员工转岗被裁,资源全浪费
    再也不怕女朋友问我二分查找了!【手绘漫画】图解二分查找(修订版)(LeetCode 704题)
    我的Hexo-Github博客搭建笔记
    J
    怎样使用npm打包公布nodejs程序包
    JQuery Jcrop—JQuery Jcrop 图像裁剪工具学习
  • 原文地址:https://www.cnblogs.com/sniffs/p/11623256.html
Copyright © 2011-2022 走看看