多线程详解

发布时间 2023-09-20 20:08:12作者: wolaile1

多线程详解

  • 线程简介
  • 线程实现(重点)
  • 线程状态
  • 线程同步(重点)
  • 线程通信问题
  • 高级主题

线程简介

Process与Thread

img
  • 程序是指令和和数据的集合,其本身没有任何运行的含义,是一个静态的概念。

  • 进程则是执行程序的一次执行过程,他是一个动态的概念。是系统资源分配的单位。

  • 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程是CPU调度和执行的单位。

    注意:很多多线程是模拟出来的,真正的线程是指有多个CPU,即多核,如服务器。如果是模拟出来的多线程,即在一个CPU的情况下,在同一个时间点,CPU只能执行一个代码,因为切换的很快,所以就有同时执行的错觉。

线程实现

创建线程

img
  • 继承Thread类,重写run方法

    package com.yuan.threadlesson;
    
    //创建线程方式一:继承Thread类, 重写run()方法,调用start开启线程
    public class TestThread1 extends Thread{
        @Override
        public void run() {
            for (int i=0;i<200;i++){
                System.out.println("nihao"+i);
            }
        }
    
        public static void main(String[] args) {
            TestThread1 testThread1 = new TestThread1();
            testThread1.start();
            for (int i = 0; i < 200; i++) {
                System.out.println("niyehao"+i);
            }
    
        }
    }
    
    
  • 实现Runnable接口。

    package com.yuan.threadlesson;
    
    public class TestThread2 implements Runnable{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println("我在看代码"+i);
            }
        }
    
        public static void main(String[] args) {
            TestThread2 testThread2 = new TestThread2();
            new Thread(testThread2).start();
    
            for (int i = 0; i < 20; i++) {
                System.out.println("nihao"+i);
            }
        }
    }
    

静态代理

线程状态

  • 线程停止

  • 线程休眠

    • Thread.sleep()
      
  • 线程礼让

    • Thread.yield()
      
  • 强制执行

    • Thread.join()
      
  • 线程优先级

    • Thread.setPriority()
      
  • 线程守护

    • Thread.setDaemon(true);//默认是false表示的 是用户线程,正常的线程都是用户线程
      

线程同步

  • 线程同步含义:多个线程操作同一个资源

  • 对比:并发,同一个对象被多个线程同时操纵

  • 形成条件:队列和锁

  • 线程同步方式:同步锁的对象应该是变化的量

    • 同步方法,synchronized 修饰方法

      //如下所示
      private synchronized void buy() {} //同步方法,synchronized默认,锁的是this
      
    • 同步块

      synchronized (obj){//obj 对象
          //执行代码块
      }
      

  • 死锁:多个线程(两个及以上)互相抱着对方需要的资源,然后形成僵持。

  • lock(锁),从JDK5.0开始,java提供了更强大的线程同步机制---通过显式定义同步锁对对象来实现同步。同步锁使用Lock对象充当

    • //定义lock锁  ReentrantLock--可重复锁
      ReentrantLock lock = new ReentrantLock();
      

线程协作

  • 线程通信

    • 生产者消费者模式(问题)
      • 对于生产者,没用生产产品之前,要通知消费者等待,而生产了产品之后,又需要马上通知消费者消费
      • 对于消费者,在消费者后,要通知生产者已经结束消费,需要生产新的产品以供消费。
      • 在生产者消费者问题中,仅有synchronized是不够的
        • synchronized可阻止并发更新同一个共享资源,实现了同步
        • synchronized不能用来实现不同线程之间的消息传递(通信)
    package com.yuan.threadlesson;
    
    //生产者消费者问题1
    public class TestPc {
        public static void main(String[] args) {
            SynContainer container = new SynContainer();
    
            new Producer(container).start();
            new Consumer(container).start();
        }
    }
    //生产者
    class Producer extends Thread{
        SynContainer container;
        public Producer(SynContainer container){
            this.container = container;
        }
        //生产
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("生产了"+i+"只鸡");
                container.push(new Chicken(i));
            }
        }
    }
    //消费者
    class Consumer extends Thread{
        SynContainer container;
    
        public Consumer(SynContainer container){
            this.container = container;
        }
        //消费
        @Override
        public void run() {
            for (int i = 0; i < 100 ; i++) {
                System.out.println("消费了--->"+container.pop().id+"只鸡");
                container.pop();
            }
        }
    }
    //生产者生产的产品
    class Chicken{
        int id;
        public Chicken(int id) {
            this.id = id;
        }
    }
    //缓存区
    class SynContainer extends Thread{
        //存放产品的仓库容量
        Chicken[] chickens = new Chicken[10] ;
        //产品数量
        int count=0;
    
        //生产者存放产品
        public synchronized void push(Chicken chicken){
            //如果生产达到消费需求,通知消费者消费
            while (count==chickens.length){
                try {
                    wait(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //如果没有满,我们需要继续生产
            chickens[count] = chicken;
            count++;
            this.notifyAll();
        }
        //消费者消费产品
        public synchronized Chicken pop(){
            while (count==0){
                //等待生产者生产,消费者等待
                try {
                    wait(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            }
            count--;
            Chicken chicken = chickens[count];
    
            this.notifyAll();
            return chicken;
        }
    }
    

使用线程池

  • JDK5.0起提供了线程池相关API:ExectutorService和EXecutors

  • package com.yuan.threadlesson;
    
    import java.util.concurrent.Executor;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestPool {
        public static void main(String[] args) {
            //1.创建服务,创建线程池
            ExecutorService service = Executors.newFixedThreadPool(10);
    
            //执行
            service.execute(new myThread());
            service.execute(new myThread());
            service.execute(new myThread());
            service.execute(new myThread());
    
            //关闭连接
            service.shutdown();
        }
    
    }
    
    
    class myThread implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 4; i++) {
                System.out.println(Thread.currentThread().getName());
            }
        }
    }