java多线程

本文详细介绍了Java中的多线程概念,包括线程的创建、生命周期、常见方法如sleep()和interrupted(),以及线程调度、线程安全问题和解决方案,如synchronized关键字的使用。此外,还讨论了守护线程、定时器、实现线程的第三种方式——FutureTask,以及wait和notify方法在生产者消费者模式中的应用。
摘要由CSDN通过智能技术生成

多线程:

1. 介绍:

  1. 什么是进程,什么是线程:

    进程是一个应用程序,线程是一个进程中的执行场景或执行单元,一个进程可以启动多个线程。java中之所以有多线程机制,目的是为了提高程序的处理效率。

  2. 在java语言中,堆内存和方法区内存共享,但是栈内存独立,一个线程一个栈。

  3. 使用了多线程机制之后,main方法结束,程序可能也不会结束。main方法结束只是主线程结束了,主栈空了,其它的栈(线程)可能还在压栈弹栈。

2. 创建线程的方式:

  1. 在java语言中,实现线程一般有两种方式:

    • 第一种方式:

      • 编写一个类,直接继承java.lang.Thread,重写run()方法

      • 创建分线程对象,调用start()方法

      • start()方法作用:启动一个分支线程,在JVM中开辟一个新的栈空间,这段代码任务完成之后,瞬间就结束了

      • 启动成功的线程会自动调用run方法,并且run方法在分支栈的底部(压栈)。run方法在分支栈的栈底部,main方法在主线程的栈底部。run和main是平级的

      • //定义线程类
        public class MyThread extends Thread{
                 
            //重写run方法
            public  void run(){
                 
                
            } 
        }
        
        //创建线程对象
        MyThread t=new MyThread();
        //启动线程
        t.start();
        
    • 第二种方式:

      • 编写一个类,实现java.lang.Runnable接口,实现run方法。比较常用。

      • //定义线程类
        public class RunnableTest implements Runnable{
                 
            //重写run方法
            public  void run(){
                 
                
            } 
        }
        
        //创建一个可运行的对象
        RunnableTest rt=new RunnableTest();
        //将一个可运行的对象封装成一个线程对象
        Thread th=new Thread(rt);
        //启动线程
        th.start();
        
    • 采用匿名内部类方式:

      public class ThreadTest04 {
             
          public static void main(String[] args) {
             
              //采用匿名内部类方式,创建线程对象
              Thread t=new Thread(new Runnable() {
             
                  @Override
                  public void run() {
             
                      for (int i=1;i<101;i++){
             
                          System.out.println("分支线程-->"+i);
      
                      }
                  }
              });
              //启动线程
              t.start();
              for (int i=1;i<101;i++){
             
                  System.out.println("main-->"+i);
      
              }
          }
      }
      
      

3. 线程的生命周期图:

在这里插入图片描述

4. 线程的常见方法:

1. 获取当前线程对象

void setName(String name); //修改线程名字
String getName() ; //获取线程名称,默认为Thread-0
static Thread currentThread(); //返回当前线程对象
  1. 代码演示:

    public class ThreadTest05 {
         
        public static void main(String[] args) {
         
            //创建线程对象
            MyThread2 t1=new MyThread2();
           // t.setName("xiaoma");
            //获取线程的名字
            String tName=t1.getName();
            System.out.println(tName);
    
            MyThread2 t2=new MyThread2();
            System.out.println(t2.getName());
            //启动线程
           t1.start();
            System.out.println(Thread.currentThread().getName());
    
    
        }
    }
    
    class MyThread2 extends  Thread{
         
        @Override
        public void run() {
         
            for (int i=0;i<100;i++){
         
                //当t1线程执行run方法,那么当前线程就是t1
                //当t2线程执行run方法,那么当前线程就是t2
                Thread currentThread=Thread.currentThread();
                System.out.println(currentThread.getName()+"---->"+i); //Thread-0--->1
            }
        }
    }
    
    

2 . sleep()方法:

  1. 关于线程的sleep()方法:

    //1. 静态方法: Thread.sleep(1000);
    //2. 参数是毫秒
    //3. 作用:让当前线程进入休眠状态,进入“堵塞状态”,放弃占用CPU时间片,让给其他线程使用
    //4. Thread.sleep()方法,可以做到间隔特定的时间,去执行一段特定的代码,每隔多久执行一次
    static void sleep(long millis);
    
  2. 代码演示:

    /*
    关于线程的sleep()方法
    * */
    public class ThreadTest06 {
         
        public static void main(String[] args) {
         
           /* try {
                //让当前线程进入休眠,睡眠5秒
                Thread.sleep(1000 *5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //5秒之后执行这里代码
            System.out.println("xiaoma");*/
    
           for(int i=0;i<10;i++){
         
               //每隔一秒,输出一次
               System.out.println(Thread.currentThread().getName()+"--->"+i);
               try {
         
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
         
                   e.printStackTrace();
               }
           }
        }
    }
    
1. 关于sleep()方法的面试题:
  1. 问题:这行代码会让线程t进入休眠状态嘛?

    不会,sleep()是静态方法和t线程没关系,在执行的时候还是会转为Thread.sleep(1000*5)。
    这行代码的作用是:让当前线程进入休眠,也就是说让main线程进入休眠

public class ThreadTest07 {
   
    public static void main(String[] args) {
   
        //创建线程对象
        Thread t=new MyThread3();
        t.setName("t");
        t.start();
        //调用sleep()方法
        try {
   
            //问题:这行代码会让线程t进入休眠状态嘛? 不会
            //sleep()是静态方法和t线程没关系
            // 在执行的时候还是会转为Thread.sleep(1000*5)
            //这行代码的作用是:让当前线程进入休眠,也就是说让main线程进入休眠
            t.sleep(1000*5);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
        //5秒之后这里才会执行
        System.out.println("hello world");

    }
}

class MyThread3 extends Thread{
   
    public void run(){
   
        for (int i=0;i<10000;i++){
   
            System.out.println(Thread.currentThread().getName()+"--->"+i);
        }
    }
}

3. 唤醒线程 interrupted():

  1. void interrupt() //依靠了java的异常处理机制,终断睡眠,会打印出异常信息
    
  2. 代码演示:

    /*
    sleep睡眠太久了,如何唤醒一个正在睡眠的线程。
    * */
    public class ThreadTest08 {
         
        public static void main(String[] args) {
         
            Thread t=new Thread(new MyRunnable2());
            t.setName("t");
            t.start();
    
            //希望5秒之后t线程醒来
            try {
         
                Thread.sleep(1000*5);
            } catch (InterruptedException e) {
         
                e.printStackTrace();
            }
            //中断t线程的线程(这种终断睡眠的方式,依靠了java的异常处理机制。)
            t.interrupt(); //干扰
        }
    }
    
    class MyRunnable2 implements Runnable{
         
    
        //重点:run()当中的异常不能throws ,只能try catch
        //因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常
        @Override
        public void run() {
         
            System.out.println(Thread.currentThread().getName()+"---> begin");
            try {
         
                // 睡眠1年
                Thread.sleep(1000*60*60*
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值