Java线程的实现方式详解(Java基础)

你好我是辰兮,很高兴你能来阅读,本篇为Java基础之多线程的实现讲解,基础知识的讲解,相关的更多,面试知识已经提前整理好文章可以阅读学习,希望对初学者有帮助。



一、文章序言

创建线程的方式一致为Java面试常见基础问题,基础学习中我们常用前两种方式,下文带大家用代码案例进一步了解相关的知识。

在这里插入图片描述

  • 常用第二种接口实现,因为实现接口的方式比继承类的方式更灵活,也能减少程序之间的耦合度。

二、继承Thread类

继承自Thread类,Thread类是所有线程类的父类,实现了对线程的抽取和封装

继承Thread类创建并启动多线程的步骤:

  • ①.定义一个类,继承自Thread类,并重写该类的run方法,该run方法的方法体就代表了线程需要完成的任务,因此,run方法的方法体被称为线程执行体
  • ②.创建Thread子类的对象,即创建了子线程
  • ③.用线程对象的start方法来启动该线程

Demo先创建一个售票线程

package demo1;

public class SellTickets extends Thread {
    //共享数据
    static int count = 100;
    @Override
    public void run() {
        //循环售票
        while(count > 0) {
            count--;
            System.out.println(Thread.currentThread().getName() + "售出了一张票,剩余" + count);
        }
    }
}

测试类

import demo1.SellTickets;

public class TheadDemo {

    public  static void main(String[] args) {
        //模拟四个售票员售票
        SellTickets s1 = new SellTickets();
        SellTickets s2 = new SellTickets();
        SellTickets s3 = new SellTickets();
       // System.out.println(s1.currentThread().getName());  //这个线程的名称是main
        s1.start();
        s2.start();
        s3.start();

    }
}

在这里插入图片描述


三、实现Runnable接口

实现Runnable接口创建并启动多线程的步骤:

  • a.定义一个Runnable接口的实现类,并重写该接口中的run方法,该run方法的方法体同样是该线程的线程执行 体
  • b.创建Runnable实现类的实例,并以此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象
  • c.调用线程对象的start方法来启动该线程

  • 继续售票的案例 应该是继承implement接口,为了简洁我写一个里面了
package demo1;

public class SellTickets {
    static int count = 100;
    static Runnable r = new Runnable() {
      @Override
      public void run() {
          while(count > 0) {
              count--;
              System.out.println(Thread.currentThread().getName() + "售出了 一张票,剩余" + count);
          }
      }
  };

    public static void main(String[] args) {
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);
        t1.start();
        t2.start();
        t3.start();
      }
}

在这里插入图片描述


四、两种实现方式的比较

①实现Runnable接口的方式

a.线程类只是实现了Runnable接口,还可以继承其他类【一个类在实现接口的同时还可以继承另外一个类】
b.可以多个线程共享同一个target对象,所以非常适合多个线程来处理同一份资源的情况
c.弊端:编程稍微复杂,不直观,如果要访问当前线程,必须使用Thread.currentThread()

② 继承Thread类的方式

a.编写简单,如果要访问当前线程,除了可以通过Thread.currentThread()方式之外,还可以使用 super关键字
b.弊端:因为线程类已经继承了Thread类,则不能再继承其他类【单继承】 实际上大多数的多线程应用都可以采用实现Runnable接口的方式来实现【推荐使用匿名内部类】java类是单知继承的


五、调用start()与run()方法的区别

Thread thread = new Thread();
thread.start();

① - start()方法会新建一个线程,并且让这个线程执行run()方法。

Thread thread = new Thread();
thread.run();

② - 调用run()也能正常执行。但是,却不能新建一个线程,而是在当前线程中调用run()方法,只是作为一个普通的方法调用。

我知道这样表达有点抽象,所有我截图了上述案例

在这里插入图片描述

在这里插入图片描述

建议:不要用run()来开启新线程,它只会在当前线程中,串行执行run()方法中的代码。


拓展一下源码的学习只截取了部分

public synchronized void start() {

    private native void start0();

    /**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }


}

在start方法里调用了一次start0方法,这个方法是一个只声明未定义的方法,并且使用了native关键字进行定义native指的是调用本机的原生系统函数。所以,调用start方法,会告诉JVM去分配本机系统的资源,才能实现多线程。


The best investment is to invest in yourself

在这里插入图片描述

2020.05.29 记录辰兮的第70篇博客

  • 35
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
`newFixedThreadPool` 是 Java线程池的一种实现方式,它可以创建一个固定大小的线程池,并且只有在池中的所有线程都处于忙碌状态时,才会将新的任务加入到队列中等待执行。 以下是 `newFixedThreadPool` 的详细解释: 1. 创建一个固定大小的线程池,该线程池中的线程数量是固定的,一旦创建便无法更改。这意味着,如果池中的所有线程都处于忙碌状态并且有更多的任务需要执行,那么这些任务将会被放置在一个队列中,等待空闲线程的出现。 2. 线程池中的所有线程都是可重用的,这意味着在执行完任务之后,线程将返回线程池并等待下一个任务的到来。 3. 线程池中的所有线程都是后台线程,这意味着它们不会阻止应用程序的关闭。 4. 线程池中的任务可以是任何实现了 `Runnable` 接口或 `Callable` 接口的对象。使用 `Callable` 接口可以允许任务返回一个值,并且可以抛出异常。 5. 线程池中的任务将按照加入队列的顺序进行执行。 6. `newFixedThreadPool` 的底层实现是一个无界的工作队列和一个固定数量的线程池。 使用 `newFixedThreadPool` 可以有效地控制线程的数量,从而避免创建过多的线程而导致系统的资源浪费和性能下降。但是,如果任务的数量过多,而线程池中的线程数量过少,那么仍然会出现任务排队等待的情况。因此,在使用 `newFixedThreadPool` 时,需要根据实际情况来确定线程池的大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员橙子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值