小王Java学习打卡day18——多线程

本文详细介绍了Java中的多线程概念,包括并行与并发的区别,线程与进程的特性,以及线程的实现方式如继承Thread类、实现Runnable接口。此外,还讲解了线程调度的原理,如抢占式调用和线程控制操作,如join、yield和线程优先级。最后,讨论了线程同步的方法,如同步代码块、同步方法和Lock锁机制,并给出了选择锁的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多线程

多行并发

  1. 需求:一边打LOL,一边听网易云音乐
  2. 问题:程序间断的问题
    • 多进程或者多线程来解决
  3. 并行:多件事情在同一时间点发生
  4. 并发:多件事情在同一时间段发生,同一时间段运行多个程序
  5. 单个cpu:一个时间点只能执行一个程序,可以交替执行

线程与进程

  1. 进程:内存中的应用程序,每个进程都是一块独立的内存空间
  2. 线程:进程中执行任务的单元,一个进程可以同时并发的运行多个线程
  3. 进程:进程有独立的内存空间,一个进程中至少有一个线程
  4. 线程:栈空间是独立的,堆空间是共享的
  5. 多线程的优势:因为堆空间是共享的,所以对内存的开销比较小
  6. 多线程取决于cpu调度
  7. java程序最少包含两个线程(主线程,GC垃圾回收线程)
  8. 线程的调度:jvm采用抢占式调用,没有采用分时调用,执行的结果是随机的

线程的实现方式

  1. 继承Thread类

    • 重写run方法

    • 启动线程,调用start

    //创建类,继承Thread
    public class MusicDemo extends Thread{
        @Override//重写run方法
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("播放音乐:"+i);
            }
        }
    }
    //启动线程
    MusicDemo musicDemo = new MusicDemo();
    musicDemo.start();
    

**注意:**线程的启动不是去手动调用run方法,需要调用线程的start方法

  1. 实现Runnable接口

    • 实现Runnable 接口,实现run方法

    • 启动:

      • 实现impl = new 实现类();

      • Thread t = new Thread (impl);

      • t.start();

        public class MusicDemo implements Runnable{
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("播放音乐:"+i);
                }
            }
        }
        
        public class RunnableDemo {
            public static void main(String[] args) {
                MusicDemo musicDemo = new MusicDemo();
                Thread thread = new Thread(musicDemo);
                thread.start();
        
                for (int i = 0; i < 100; i++) {
                    System.out.println("打游戏:"+i);
                }
            }
        }
        
  2. 使用匿名内部类的方式创建线程(某个线程只需要使用一次)

线程调度

  1. 线程的控制操作:

  2. 线程的合并

    • join 方法

      MusicDemo musicDemo = new MusicDemo();
      musicDemo.start();
      
      for (int i = 0; i <20; i++) {
          System.out.println("打游戏:"+i);
          if(i==6){
              musicDemo.join();
          }
      }
      
  3. 守护线程:GC使用的

    • 目的:为其他线程服务的(GC典型的守护线程)

    • 主线程结束,守护线程也结束

    • 创建线程默认是前台线程(主线程)

    • 获取守护线程 : thread.setDaemon(true);

      daemonThread.setDaemon(true);//守护线程,必须设置在start();方法前面,主线程结束,它也结束
      daemonThread.start();
      
  4. 获取当前线程的名称

    • Thread.currentThread().getName();
  5. 线程设置优先级

    • 优先级的高低并不会完全影响执行的先后顺序,只是优先级高,执行的机会大

      public final static int MAX_PRIORITY = 10;
      public final static int NORM_PRIORITY = 5;
      public final static int MIN_PRIORITY = 1;
      
  6. 线程让位

    • yield 方法:当前线程自愿让出cpu资源

    • yield 和 sleep区别:

      • 都能使当前运行线程放弃cpu运行机会,把机会让给其他线程
      • sleep给线程机会的时候,不考虑优先级
      • yield 只会给相同优先级或者更高优先级机会
      public class Thread1 extends Thread{
          @Override
          public void run() {
              for (int i = 0; i < 10; i++) {
                  System.out.println("线程1:"+i);
              }
              Thread.yield();//让出线程
          }
      }
      
  7. 线程同步

    1. 需求:猴子吃香蕉(30根香蕉,3个猴子)

      • 使用继承 Thread 方式

        • 同一个编号的香蕉被多个猴子吃
      • 使用实现Runnable接口

        private int num = 30;
        @Override
        public void run() {
            for (int i = 0; i < 30; i++) {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + "吃了编号为:" + num-- + "的香蕉。");
                }
            }
        }
        
        public static void main(String[] args) {
            Banana banana = new Banana();
            Thread thread1 = new Thread(banana,"AAA猴子");
            thread1.start();
            Thread thread2 = new Thread(banana,"BBB猴子");
            thread2.start();
            Thread thread3 = new Thread(banana,"CCC猴子");
            thread3.start();
        }
        
  8. 解决方案:多个猴子吃到同一个香蕉

    • 同步代码块

      • 语法

        synchronized(同步锁){
            业务逻辑
        }
        
    • 同步方法

      • 语法

        synchronized  pubilc void eat(){
            //业务逻辑
        }
        
    • 锁机制(Lock)

      • 语法
      //创建锁
         private final Lock lock = new ReentrantLock();
      //上锁
       lock.lock();
      //释放锁
       lock.unlock();同步代码块,同步方法,同步锁的选用?
      
  9. 同步代码块,同步方法,同步锁如何选用?

    • 尽量减少锁的作用域(synchronized锁方法)

    • 建议使用同步锁Lock,可以很好地控制锁的作用域

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值