java多线程编程_Thread类_线程状态的理解(1)

举报
bug郭 发表于 2022/09/30 22:53:07 2022/09/30
【摘要】 大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流作者简介:CSDN java领域新星创作者blog.csdn.net/bug…掘金LV3用户 juejin.cn/user/bug…阿里云社区专家博主,星级博主,developer.a...

大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流

作者简介:

本节目标

  • 学习java多线程编程!

  • 了解java中的Thread类的基本使用!

  • 掌握Thread创建线程对象的5种方法

  • 学习Thread类中的一些常用属性和方法!

    Thread

    我们知道操作系统中的线程是并发执行的!
    Thread类是java给我们提供的一个类,通过Thread可以实现java并发编程!Thread类可以视为java标准库提供的API
    创建好的Thread实例和操作系统的线程一一对应!!!

    Thread是在java.lang包下的类无需导入!!!

    了解并发编程

    public class Thread_4 {
      public static void main(String[] args) {
      //自己创建的线程t1
          Thread t1 = new Thread(()->{
              while (true){
                  System.out.println("hello Thread!");
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
              }
          });
          t1.start();//执行t1
          while (true){
              //主线程 main线程 一个java进程中自动创建了main线程!!!
              System.out.println("hello main");
              try {
                  Thread.sleep(1000); //睡眠1s 阻塞线程!在这1s不然上cpu
              }catch (InterruptedException e){
                  e.printStackTrace();
              }
          }
      }
    

}

``

在这里插入图片描述
我们可以看到t1线程和main并发执行!这里的并发包括并发和并行!
我们也不知道cup啥时候让这两个线程并发,啥时候并行!
这些都是操作系统的调度问题!!!

多线程优势

当我们要同时自增两数时,采用多线程编程和单线程编程又有啥区别呢,让我们看看下方代码就知道了!

//自增两数
public class Thread_8 {
  private static final long count=100_0000_0000L;
  public static void main(String[] args) throws InterruptedException{
          concurrent();//多线程并行执行
          serial(); //单线程串行执行

  }
  public static void concurrent() throws InterruptedException {
      //多线程
      long beign = System.nanoTime();//获取当前时间戳毫秒数
      Thread t1 = new Thread(()->{
          long a = 0;
          for (int i = 0; i < count; i++) {
              a++;
          }
      });
      t1.start();
      long b = 0;
      for (int i = 0; i < count; i++) {
          b++;
      }
      t1.join();
      long end = System.nanoTime();//获取结束时间戳
      System.out.println("并行:"+(end-beign));
  }
  public static void serial(){
      long begin = System.nanoTime();
      long a = 0;
      for (int i = 0; i < count; i++) {
          a++;
      }
      long b = 0;
      for (int i = 0; i < count; i++) {
          b++;
      }
      long end = System.nanoTime();
      System.out.println("串行:"+(end-begin));
  }
}

在这里插入图片描述

  • 我们并不知道何时并发的两个线程是并行还是并发,这都是取决于线程的调度器的调取问题!

  • 并发编程也不一定比串行快,如果自增的两数较小,创建变量的时间占据该线程执行的大部分时间,那么就达不到并发编程的优势!

  • 是否采用多线程编程视情况而定,并非无脑多线程!

    一个java进程中自动会创建一个main线程!!!并在操作系统有对应该线程!

我们如何查看线程是否在操作系统中创建成功呢?
我们再jdk中的lib文件夹下打开jconsole.jar文件便可以查看线程!!!
在这里插入图片描述
我们打开便可以看到我们创建的java线程以及jvm自带的一些线程!!!

创建Thread实例

  • 方法一
    创建Thread子类,重写run方法
class Mythread extends Thread{
    @Override
    public void run() {//描述线程要执行的任务!
        System.out.println("run");
    }
}
public class Thread_1 {
    public static void main(String[] args) {
        Thread t1 = new Mythread();
        t1.start();
    }
}

这里的run只是描述该线程需要执行那些任务!这只是创建了一个类! 线程的执行需要该线程实例执行start方法!执行start方法后操作系统才会创建对应的线程!
在这里插入图片描述

  • 方法二
    创建一个类实现Runnable接口,重写run方法,再将该类传参到创建Thread对象的构造方法!
class MyRun implements Runnable{
    @Override
    public void run() {
        //描述任务
        System.out.println("实现Runnable接口创建线程!");
    }
}
public class Thread_2 {
    public static void main(String[] args) {
        //将实现Runnable接口的对象传入Thread构造方法中!
        Thread t1 = new Thread(new MyRun());
        t1.start();//创建线程
    }
}


我们来看看Thread类的4个构造方法!
在这里插入图片描述
Thread() 无参构造
通过继承Thread
Thread(Runnable target);
传入Runnable对象
Thread(String name);
给线程命名,便于程序员调试

在这里插入图片描述

  • 方法三
    Thread匿名内部类
public class Thread_3 {
   public static void main(String[] args) {
       Thread t1 = new Thread(){
           @Override
           public void run() {
               System.out.println("Thread匿名内部类!");
           }
       };
       t1.start();
   }
}

在这里插入图片描述

  • 方法四
    Runnable接口匿名内部类
public class Thread_5 {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Runnable匿名内部类!");
            }
        });
        t1.start();
    }
}

在这里插入图片描述

  • 方法五
    lambda表达式
    方法四/五的升级版!
public class Thread_6 {
   public static void main(String[] args) {
       Thread t1 = new Thread(()->{
           System.out.println("lambda表达式!");
       });
       t1.start();
   }
}

在这里插入图片描述
我们比较推荐使用Runnable接口创建线程实例!
因为实现Runnable接口,可以让线程和线程执行的任务,更好进行解耦!!!
简单说就是Runnable方法创建线程实例, Runnable可以将线程和线程任务分开!
我们实现一个Runnable接口,我们只需要把入线程任务描述出来,不必关系那个线程执行该线程任务!,可能是线程,可能是进程,可能是协程,这些我们都不用关系!!!

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。