第20章 Java 多线程

多线程

前言

一、线程的创建

1、继承Thread类

2、实现Runnable接口

二、线程的生命周期

三、操作线程的方法

1、线程的休眠

2、线程的加入

3、线程的礼让

4、线程的优先级

四、线程同步

End

前言

Java是支持多线程的编程语言,所谓多线程就是程序能够同时完成多种操作。

计算机完成可以多种操作同时进行,这种思想在Java中被称为并发,而将并发完成的多种操作被称为线程。

一、线程的创建

在Java中线程的创建一般分为两种方式:

继承Thread类创建

实现Runnable接口创建

1、继承Thread类

Java中的Thread类是java.lang包中的核心类,它代表一个线程。它主要用于创建新线程并在其中执行自定义任务。

Thread类的主要特点包括:

继承性:Thread类是java.lang.Object的子类,因此可以继承Object类的属性和方法。

抽象性:Thread类是一个抽象类,这意味着它不能直接实例化。为了使用Thread类,我们需要创建一个Thread的子类,并重写其run()方法。

线程安全性:Thread类是线程安全的,这意味着多个线程可以同时调用Thread类的方法,而不会导致数据不一致或其他并发问题。

常用方法:Thread类有许多有用的方法,包括start()(启动线程)、run()(执行线程)、sleep()(使线程休眠)、interrupt()(中断线程)等。

继承Thread类创建一个新的线程语法:

public class MyThread extends Thread {  

    @Override  

    public void run() {  

        // 在这里编写线程需要执行的代码  

        System.out.println("My thread is running.");  

    }  

}

完成线程真正功能的代码放置在run方法中执行,该线程在执行完run方法中的代码后就会停止。

示例:

public class demo_1 {

    public static void main(String[] args) {

        /*

            实现方式:1

            自定义一个类继承Thread、或者构建Thread对象,重写run方法

            重写run方法

            启动线程

        */

        MyThread t1=new MyThread();

        MyThread t2=new MyThread();

        

        // 为线程指定名字

        t1.setName("线程一");  

        t2.setName("线程二");

    

        t1.start(); // 开启线程

        t2.start(); // 开启线程

    }

}

class MyThread extends Thread{

    @Override

    public void run() {

        for (int i = 0; i < 10; i++) {

            System.out.println(getName()+ "芜湖");

        }

    }

}

2、实现Runnable接口

上一种方式创建线程的方式,是通过继承Thread类的方式创建的,但是Java是只支持单继承的语言,所以如果通过上一个方式创建线程的话,拓展性不太好。因此就可以使用实现接口的方式来创建线程。

实现过程:

自定义一个类实现Runnable接口

重写run方法,

创建自己类的对象,

创建Thread对象开启线程

示例:

package text_1;

public class demo_2 {

    public static void main(String[] args) {

        /*

        * 第二种实现方式:

        * 自定义一个类实现Runnable接口

        * 重写run方法,

        * 创建自己类的对象,

        * 创建Thread对象开启线程

        *

        * */

        MyRun mr=new MyRun();

        Thread t1=new Thread(mr);

        Thread t2=new Thread(mr);

        t1.setName("芜湖");

        t2.setName("呀呼");

        t1.start();

        t2.start();

    }

}

class MyRun implements Runnable{

    @Override

    public void run() {

        Thread thread = Thread.currentThread(); // 获取当前线程的对象

        for (int i = 0; i < 10; i++) {

            System.out.println(thread.getName()+ "爱坤");

        }

    }

}

只所以能通过这中方式创建线程,是因为Thread类就是Runnable接口的实现类。

在这里插入图片描述

且在Thread类中的构造方法中有Runnable的实例,使用这种构造方法就可以将Runnable实例与Thread实例相关联,也就是说,使用这种构造方法后,Thread类调用的run方法就是Runnable中的run方法。

三、操作线程的方法

操作线程的方法有很多,这些方法可以使得线程从某种状态过度到另一种状态。

1、线程的休眠

sleep方法

在这里插入图片描述

该方法使得当前线程在指定的时代内不会进入就绪状态。

该方法是被static修饰的,所以可以直接使用类名调用。

示例:

package text_2;

public class demo_1 {

    public static void main(String[] args) {

        MyThread mt1 = new MyThread();

        mt1.start();

    }

}

class MyThread extends Thread{

    @Override

    public void run() {

        for (int i = 0; i < 10; i++) {

            try {

                // 以毫秒为单位

                Thread.sleep(1000);

            } catch (InterruptedException e) {

                throw new RuntimeException(e);

            }

            System.out.println("芜湖");

        }

    }

}

2、线程的加入

join方法

在Java多线程编程中,join方法是一个非常重要的概念。它用于确保主线程等待其他线程完成其任务后再继续执行。当一个线程调用另一个线程的join方法时,调用线程会阻塞,直到被调用线程结束执行。

join方法通常在创建线程时使用,以确保主线程不会在子线程完成前结束。这有助于防止数据竞争和其他并发问题。

在这里插入图片描述

示例:

package text_2;

public class demo_1 {

    public static void main(String[] args) throws InterruptedException {

        MyThread mt1 = new MyThread();

        MyThread mt2 = new MyThread();

        mt1.setName("wuhu");

        mt2.setName("yahu");

        mt1.start();

        mt1.join();

        mt2.start();

    }

}

class MyThread extends Thread{

    @Override

    public void run() {

        for (int i = 0; i < 4; i++) {

            try {

                // 以毫秒为单位

                Thread.sleep(10);

            } catch (InterruptedException e) {

                throw new RuntimeException(e);

            }

            System.out.println(getName());

        }

    }

3、线程的礼让

在Java中,线程礼让是指在线程A和线程B执行的时候,线程B由于某种原因需要先一步执行,那么可以对线程A执行yield方法,先让线程B执行一步。请注意,这里和join方法不一样,join方法是将CPU资源全都分出,直到线程B执行完,而yield只会让出一步。

4、线程的优先级

在Java中,线程的优先级是一个整数,范围从1(最低优先级)到10(最高优先级)。默认情况下,新创建的线程的优先级为5。线程优先级越小,线程越优先被执行;线程优先级越大,线程越后被执行。可以通过Thread类的setPriority(int)方法来设置线程的优先级。

请注意,如果优先级相同的线程同时存在,那么会按照提交顺序(也就是代码编写顺序)执行的方式。

package text_2;

public class demo_2 {

    public static void main(String[] args) {

        /*

        * 设置优先级 :setPriority()

        * 获取优先级 : get

        * 守护线程 :setDaemon(boolean)

        * 细节:守护线程会在所有非守护线程结束后结束

        * */

// System.out.println(Thread.currentTh

你可能感兴趣的:(java,开发语言)