JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口

简介: JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持一.

JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口


开始挑战一些难度了,线程和I/O方面的操作了,继续坚持

一.Thread

如何在自定义的代码中,自定义一个线程呢?

这里写图片描述

我们查看API文档,我们要启动一个线程,先实现一个子类,

package com.lgl.hellojava;

public class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println("我是一个线程");
    }
}

我们要调用它的话,只需要start就可以

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

这样就会执行我们的run方法

这里写图片描述

我们来理一下思路,线程有两种创建方式,我们先将第一种:

  • 1.继承Thread 类
  • 2.复写Thread类的run方法
  • 3.调用线程的start方法
    • 该方法有两个作用,启动线程和调用run方法

我们可以把代码改一下

package com.lgl.hellojava;

//公共的   类   类名
public class HelloJJAVA {

    public static void main(String[] args) {

        MyThread thread = new MyThread();
        thread.start();
        for (int i = 0; i < 1140; i++) {
            System.out.println("Hello JAVA");
        }
    }

}

class MyThread extends Thread {

    @Override
    public void run() {
        for (int i = 0; i < 1140; i++) {
            System.out.println("我是一个线程");
        }
    }
}

这样输出多少?

这里写图片描述

你注意一下,他们交叉输出了,这种,就是多线成,两个线程同时在跑,都在获取cpu的使用权,cpu执行到谁,谁就执行,明确一点,在某一个时刻,只能有一个程序在运行(多核除外),cpu在做着快速的切换以达到看上去是同时运行的效果

我们可以形象的把多线成的运行,形容为在互相抢夺CPU的资源,那么这就是多线成的一个特性叫随机性,谁抢到谁执行,但是执行多长,cpu说了算

二.run和start的特点

为什么要覆盖run方法

Thread类用于描述线程,该类就定义了一个功能,用于存储线程要运行的代码,该存储功能就是run方法

也就是说Thread类汇总的run方法是用于存储线程执行的代码

目的:将自定义的代码存储在run方法中让线程运行

三.线程运行状态

线程运行会有几种状态,我们要了解他的状态,才能了解他运行的原理,我们先来看一张图

这里写图片描述

我们一步步来分析,首先线程的第一种状态是创建,你new一个线程就是被创建了,紧接着,就是运行的状态,他们的过程,就是start,当然,线程还有一种为冻结,处于某一种状态,就交冻结,他们通过sleep来交替。最后就是线程结束了,通过stop,当然,还有其他一些状态,比如阻塞,这是临时状态,这是具备运行资格,但是没有执行权

四.获取线程对象和名称

线程都是有名称的,通过格式Thread-编号来区分,我们可以这样来验证

package com.lgl.hellojava;

//公共的   类   类名
public class HelloJJAVA {

    public static void main(String[] args) {

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

    }

}

class MyThread extends Thread {

    @Override
    public void run() {

        System.out.println("线程名称:"+this.getName());
    }
}

它输出的结果就是

这里写图片描述

他是从0开始,当然,他既然有getrName,那肯定有setName方法,其实他初始化的时候就有方法,父类已经给我们提供好了

package com.lgl.hellojava;

//公共的   类   类名
public class HelloJJAVA {

    public static void main(String[] args) {

        MyThread thread = new MyThread("hello");
        thread.start();

    }

}

class MyThread extends Thread {

    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {

        System.out.println("线程名称:"+this.getName());
    }
}

那么我们输出的结果

这里写图片描述

它还可以通过Thread.currentThread()来获取对象名称,它等同于this.getName();

五.多线程实例演示

我们来一个简单的实例来结束本篇blog,那就是卖票了,很多窗口都能卖票,这就是同时运行

package com.lgl.hellojava;

import javax.security.auth.callback.TextInputCallback;

//公共的   类   类名
public class HelloJJAVA {

    public static void main(String[] args) {

        /**
         * 需求:简单的卖票程序,多个线程同时卖票
         */
        MyThread my1 = new MyThread();
        MyThread my2 = new MyThread();
        MyThread my3 = new MyThread();
        MyThread my4 = new MyThread();

        my1.start();
        my2.start();
        my3.start();
        my4.start();
    }

}

/**
 * 卖票程序
 * 
 * @author LGL
 *
 */
class MyThread extends Thread {

    // 票数
    private int tick = 100;

    @Override
    public void run() {
        while (true) {
            if (tick > 0) {
                System.out.println(currentThread().getName()+"卖票:" + tick--);
            }
        }
    }
}

我们这样就实现了票卖了,但是这里出了一个问题,四个线程,他一共卖了400张票,那可不行,火车就一百张票,这是不符合规则的,我们需要怎么改?让四个对象共享一个票数,那我们就需要静态了

// 票数
private static int tick = 100;

但是我们一般不定义静态,他的生命周期有点长,我们换一种角度考虑,其实这就关乎到创建方法了,我们在之前就讲个,线程创建有两种方法。

六.Runnable接口

我们需要使用第二种方法,所以是这样写的,实现Runnable的接口

package com.lgl.hellojava;

import javax.security.auth.callback.TextInputCallback;

//公共的   类   类名
public class HelloJJAVA {

    public static void main(String[] args) {

        /**
         * 需求:简单的卖票程序,多个线程同时卖票
         */
        MyThread myThread = new MyThread();
        Thread t1 = new Thread(myThread);
        Thread t2 = new Thread(myThread);
        Thread t3 = new Thread(myThread);
        Thread t4 = new Thread(myThread);

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }

}

/**
 * 卖票程序
 * 
 * @author LGL
 *
 */
class MyThread implements Runnable {

    // 票数
    private  int tick = 100;

    @Override
    public void run() {
        while (true) {
            if (tick > 0) {
                System.out.println("卖票:" + tick--);
            }
        }
    }
}

我们得到的输出结果就正确了

这里写图片描述

创建线程的第二种方式,实现Runnable接口

  • 1.定义类实现Runnable接口
  • 2.覆盖Runnable接口的run方法
    • 将线程要运行的代码存放在该run方法中
  • 3.通过Thread类建立线程对象
  • 4.将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
    • 为什么要将Runnable接口的子类对象传递给Thread的构造函数,因为,自定义的run方法所属的对象是Runnable接口的子类对象,所以要让线程去指定对象的run方法,就必须明确该run方法所属的对象
  • 5.调用Thread类的start方法开启线程并调用Runnable接口的run方法

这两种方式有什么区别呢?

  • 实现方式好处,避免了单继承的局限性,在定义线程时,建议使用实现方式
  • 线程代码存放的位置不一样

小伙伴们有没有对线程了解的更深刻一点呢?不明白没关系,我们下篇还是接着讲线程,如果有兴趣可以加入群:555974449,欢迎一起交流

目录
相关文章
|
3月前
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
3月前
|
安全 Java API
【JavaEE】多线程编程引入——认识Thread类
Thread类,Thread中的run方法,在编程中怎么调度多线程
|
4月前
|
Java C# Python
线程等待(Thread Sleep)
线程等待是多线程编程中的一种同步机制,通过暂停当前线程的执行,让出CPU时间给其他线程。常用于需要程序暂停或等待其他线程完成操作的场景。不同语言中实现方式各异,如Java的`Thread.sleep(1000)`、C#的`Thread.Sleep(1000)`和Python的`time.sleep(1)`。使用时需注意避免死锁,并考虑其对程序响应性的影响。
129 8
|
4月前
|
Java 网络安全 Maven
Exception in thread "main" java.lang.NoSuchMethodError: okhttp3.OkHttpClient$Builder.sslSocketFactory(Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder; 问题处理
【10月更文挑战第26天】Exception in thread "main" java.lang.NoSuchMethodError: okhttp3.OkHttpClient$Builder.sslSocketFactory(Ljavax/net/ssl/SSLSocketFactory;Ljavax/net/ssl/X509TrustManager;)Lokhttp3/OkHttpClient$Builder; 问题处理
127 2
|
4月前
|
安全 Java
在 Java 中使用实现 Runnable 接口的方式创建线程
【10月更文挑战第22天】通过以上内容的介绍,相信你已经对在 Java 中如何使用实现 Runnable 接口的方式创建线程有了更深入的了解。在实际应用中,需要根据具体的需求和场景,合理选择线程创建方式,并注意线程安全、同步、通信等相关问题,以确保程序的正确性和稳定性。
191 11
|
5月前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
104 2
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
本文详细介绍了如何在Linux中通过在业务线程中注册和处理信号。我们讨论了信号的基本概念,并通过完整的代码示例展示了在业务线程中注册和处理信号的方法。通过正确地使用信号处理机制,可以提高程序的健壮性和响应能力。希望本文能帮助您更好地理解和应用Linux信号处理,提高开发效率和代码质量。
47 17
|
1月前
|
Linux
Linux编程: 在业务线程中注册和处理Linux信号
通过本文,您可以了解如何在业务线程中注册和处理Linux信号。正确处理信号可以提高程序的健壮性和稳定性。希望这些内容能帮助您更好地理解和应用Linux信号处理机制。
58 26
|
3月前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
277 2
|
3月前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####

热门文章

最新文章