多线程 Java


任何应用程序都可以有多个进程(实例)。每个进程都可以分配为单个线程或多个线程。我们将在本教程中了解如何同时执行多个任务,并了解有关线程和线程间同步的更多信息。

什么是单线程?

单线程 Java 基本上是轻量级的最小处理单元。 Java 通过使用“Thread 类”来使用线程。有两种类型的线程 - 用户线程和守护线程 (当我们想要清理应用程序时,会使用守护线程,这些线程在后台使用)。当应用程序首次启动时,会创建用户线程。之后,我们可以创建许多用户线程和守护线程。

单线程示例:

package demotest;

public class GuruThread
{
       public static void main(String[] args) {
              System.out.println("Single Thread");
       }
}

单线程的优点:

  • 由于系统中只执行单线程,因此减少了应用程序的开销
  • 此外,它还降低了应用程序的维护成本。

什么是多线程 Java?

多线程 in Java 是同时执行两个或多个线程以最大程度地利用 CPU 的过程。多线程应用程序执行两个或多个并发运行的线程。因此,它也被称为并发 Java。每个线程并行运行。多个线程不分配单独的内存区域,因此可以节省内存。此外,线程之间的上下文切换所需的时间更少。

多线程示例:

package demotest;
public class GuruThread1 implements Runnable
{
       public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

多线程的优点:

  • 由于线程是独立的,因此用户不会被阻塞,我们可以同时执行多个操作
  • 因此线程是独立的,如果一个线程遇到异常,其他线程不会受到影响。

线程生命周期 Java

线程的生命周期:

线程生命周期 Java
线程生命周期 Java

线程的生命周期分为多个阶段,如上图所示:

  1. 全新
  2. 可运行
  3. 运行
  4. 等候
  1. 新: 在此阶段,使用“Thread 类”创建线程。它将保持此状态直到程序 启动 线程。又称天生线程。
  2. 可运行: 在这个页面中,线程实例通过 start 方法调用。线程控制权交给调度程序来完成执行。是否运行线程取决于调度程序。
  3. 运行: 当线程开始执行时,状态将更改为“运行”状态。调度程序从线程池中选择一个线程,并开始在应用程序中执行。
  4. 等候: 这是线程必须等待的状态。由于应用程序中有多个线程在运行,因此线程之间需要同步。因此,一个线程必须等待,直到另一个线程执行完毕。因此,此状态称为等待状态。
  5. 已死: 这是线程终止时的状态。线程处于运行状态,一旦完成处理,它就处于“死亡状态”。


多线程方法 Java

一些常用的线程方法有:

付款方式 描述
开始() 此方法启动线程的执行,并 JVM 调用线程上的 run() 方法。
睡眠(int 毫秒) 此方法使线程休眠,因此线程的执行将暂停几毫秒,然后线程再次开始执行。这有助于线程同步。
getName() 它返回线程的名称。
设置优先级(int 新优先级) 它改变线程的优先级。
屈服 () 它导致当前线程停止并且其他线程执行。

计费示例: 在此多线程程序中 Java 例如,我们将创建一个线程并探索可用于线程的内置方法。

package demotest;
public class thread_example1 implements Runnable {
    @Override
    public void run() {
    }
    public static void main(String[] args) {
        Thread guruthread1 = new Thread();
        guruthread1.start();
        try {
            guruthread1.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        guruthread1.setPriority(1);
        int gurupriority = guruthread1.getPriority();
        System.out.println(gurupriority);
        System.out.println("Thread Running");
  }
}

代码说明:

  • 代码行2: 我们正在创建一个实现 Runnable 接口的类“thread_Example1”(它应该由任何实例旨在由线程执行的类来实现。)
  • 代码行4: 它重写了 Runable 接口的 Run 方法,因为必须重写该方法
  • 代码行6: 这里我们定义了主要方法,我们将在该方法中启动线程的执行。
  • 代码行7: 这里我们通过实例化一个新的线程类来创建一个名为“guruthread1”的新线程。
  • 代码行8: 我们将使用“guruthread1”实例的线程的“start”方法。这里线程将开始执行。
  • 代码行10: 这里我们使用“guruthread1”实例的线程的“sleep”方法。因此,线程将休眠 1000 毫秒。
  • 代码9-14: 这里我们将 sleep 方法放在 try catch 块中,因为发生了检查异常,即中断异常。
  • 代码行15: 这里我们将线程的优先级从原来的优先级设置为 1
  • 代码行16: 这里我们使用 getPriority() 获取线程的优先级
  • 代码行17: 这里我们打印从 getPriority 获取的值
  • 代码行18: 这里我们正在编写线程正在运行的文本。

执行上述代码时,您将获得以下输出:

线程示例 Java

输出:

5 是线程优先级,Thread Running 是我们代码输出的文本。

Java Thread Sync汉化

在多线程中,程序具有异步行为。如果一个线程正在写入一些数据,而另一个线程同时正在读取数据,则可能会在应用程序中造成不一致。当需要由两个或多个线程访问共享资源时,就会使用同步方法。 Java 提供了同步方法来实现同步行为。

在这种方法中,一旦线程进入同步块,其他线程就不能对同一对象调用该方法。所有线程都必须等到该线程完成同步块并退出。这样,同步有助于多线程应用程序。一个线程必须等到另一个线程完成其执行,然后其他线程才允许执行。

它可以写成以下形式:

Synchronized(object)
{  
        //Block of statements to be synchronized
}

多线程 Java 示例程序

在这个多线程中 Java 例如,我们将取两个线程并获取线程的名称。

Example1:

GuruThread1.java
package demotest;
public class GuruThread1 implements Runnable{

    /**
     * @param args
     */
    public static void main(String[] args) {
        Thread guruThread1 = new Thread("Guru1");
        Thread guruThread2 = new Thread("Guru2");
        guruThread1.start();
        guruThread2.start();
        System.out.println("Thread names are following:");
        System.out.println(guruThread1.getName());
        System.out.println(guruThread2.getName());
    }
    @Override
    public void run() {
    }
}

代码说明:

  • 代码行3: 我们采用了实现 Runnable 的类“GuruThread1”(它应该由任何实例旨在由线程执行的类来实现。)
  • 代码行8: 这是该类的主要方法
  • 代码行9: 这里我们实例化 Thread 类并创建一个名为“guruThread1”的实例并创建一个线程。
  • 代码行10: 这里我们实例化 Thread 类并创建一个名为“guruThread2”的实例并创建一个线程。
  • 代码行11: 我们正在启动线程,即 guruThread1。
  • 代码行12: 我们正在启动线程,即 guruThread2。
  • 代码行13: 输出文本为“线程名称如下:”
  • 代码行14: 使用线程类的方法 getName() 获取线程 1 的名称。
  • 代码行15: 使用线程类的方法 getName() 获取线程 2 的名称。

执行上述代码时,您将获得以下输出:

Java 多线程示例

输出:

线程名称在此处输出为

  • Guru1
  • Guru2

例如2:

在此多线程中 Java 例如,我们将学习重写 Runnable 接口的 run() 和 start() 方法,并创建该类的两个线程并相应地运行它们。

另外,我们还有两门课程,

  • 一个实现可运行接口,另一个
  • 另一个将具有主要方法并相应执行。
package demotest;
public class GuruThread2 {
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  GuruThread3 threadguru1 = new GuruThread3("guru1");
  threadguru1.start();
  GuruThread3 threadguru2 = new GuruThread3("guru2");
  threadguru2.start();
 }
}
class GuruThread3 implements Runnable {
 Thread guruthread;
 private String guruname;
 GuruThread3(String name) {
  guruname = name;
 }
 @Override
 public void run() {
  System.out.println("Thread running" + guruname);
  for (int i = 0; i < 4; i++) {
   System.out.println(i);
   System.out.println(guruname);
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    System.out.println("Thread has been interrupted");
   }
  }
 }
 public void start() {
  System.out.println("Thread started");
  if (guruthread == null) {
   guruthread = new Thread(this, guruname);
   guruthread.start();
  }
 }
}

代码说明:

  • 代码行2: 这里我们采用一个类“GuruThread2”,其中包含主要方法。
  • 代码行4: 这里我们采用了该类的主要方法。
  • 代码行6-7: 这里我们创建 GuruThread3 类(在下面的代码行中创建)的一个实例作为“threadguru1”,并且启动线程。
  • 代码行8-9: 这里我们创建类 GuruThread3 的另一个实例(在下面的代码行中创建)作为“threadguru2”,并且启动线程。
  • 代码行11: 这里我们创建一个类“GuruThread3”,它实现了可运行接口(它应该由任何实例旨在由线程执行的类来实现)。
  • 代码行13-14: 我们采用两个类变量,其中一个是线程类类型,另一个是字符串类类型。
  • 代码行15-18: 我们正在重写 GuruThread3 构造函数,它接受一个字符串类型(即线程名称)的参数,该参数被分配给类变量 guruname,从而存储了线程的名称。
  • 代码行20: 这里我们重写了 runnable 接口的 run() 方法。
  • 代码行21: 我们使用 println 语句输出线程名称。
  • 代码行22-31: 这里我们使用一个 for 循环,计数器初始化为 0,并且不应小于 4(我们可以取任意数字,因此此处循环将运行 4 次)并增加计数器。我们打印线程名称,并在 try-catch 块中让线程休眠 1000 毫秒,因为 sleep 方法引发了已检查异常。
  • 代码行33: 这里我们重写了可运行接口的启动方法。
  • 代码行35: 我们正在输出文本“线程已启动”。
  • 代码行36-40: 这里我们采用 if 条件来检查类变量 guruthread 是否有值。如果为空,则使用线程类创建一个实例,该实例以名称作为参数(其值在构造函数中分配)。之后使用 start() 方法启动线程。

执行上述代码时,您将获得以下输出:

多线程示例 Java

输出:

因此有两个线程,我们收到两次“线程已启动”消息。

我们得到了线程的名称,因为我们已经输出它们了。

它进入 for 循环,我们在其中打印计数器和线程名称,计数器从 0 开始。

循环执行三次,中间线程休眠 1000 毫秒。

因此,首先,我们得到 guru1,然后是 guru2,然后再次是 guru2,因为线程在这里休眠 1000 毫秒,然后是下一个 guru1,然后是 guru1,线程休眠 1000 毫秒,所以我们得到 guru2,然后是 guru1。

结语

在本教程中,我们看到了多线程应用程序 Java 以及如何在 Java.

  • 解释多线程 Java:在多线程中,用户不会被阻塞,因为线程是独立的,并且可以同时执行多个操作
  • 线程生命周期的各个阶段包括:
    • 全新
    • 可运行
    • 运行
    • 等候
  • 我们还了解到 同步 线程之间,这有助于应用程序顺利运行。
  • 多线程编程 Java 使得更多的应用任务变得更容易。