Java 多线程创建

本文介绍了Java多线程的基本概念,包括线程对象、线程状态和线程同步。创建线程可以通过实现Runnable接口或继承Thread类,线程状态包括NEW、RUNNABLE等。线程同步可通过synchronized关键字或Lock对象实现,确保并发安全。
摘要由CSDN通过智能技术生成

Java多线程是Java语言中的一个重要特性,它允许程序在同一个进程中执行多个并发任务。Java多线程为Java应用程序提供了更好的性能和响应能力。本篇博客将介绍Java多线程的基本概念、创建和启动线程的方法、线程状态、线程同步和线程池等内容。

基本概念

多线程是指在同一个进程内,同时执行多个线程的技术。每个线程都有自己的程序计数器、栈和本地变量等。Java多线程是Java语言中的一个重要特性,它允许程序在同一个进程中执行多个并发任务。Java中的多线程实现是基于线程对象的,每个线程都对应一个Thread类的实例。

Java多线程有以下几个基本概念:

  • 线程对象:Java线程是通过创建线程对象来实现的。线程对象是Thread类的一个实例,它封装了线程的状态和行为。
  • 线程状态:线程可以处于不同的状态,比如新建、运行、等待、阻塞、终止等状态。
  • 线程同步:线程同步是指多个线程协同工作,共同完成任务。线程同步可以通过锁、信号量、条件变量等机制来实现。
  • 线程通信:线程通信是指多个线程之间的数据交换和互相协作。线程通信可以通过共享内存、消息队列、管道等机制来实现。

创建和启动线程

Java中创建线程的方法有两种,一种是实现Runnable接口,另一种是继承Thread类。下面分别介绍这两种方法。

实现Runnable接口

实现Runnable接口是Java中创建线程的推荐方法。实现Runnable接口可以将线程的任务逻辑与线程对象分离,使得代码更加清晰和可维护。实现Runnable接口需要实现run()方法,在run()方法中编写线程的任务逻辑。

下面是一个实现Runnable接口的例子:

class MyRunnable implements Runnable {
  public void run() {
    System.out.println("Hello from MyRunnable!");
  }
}

public class Main {
  public static void main(String[] args) {
    Thread thread = new Thread(new MyRunnable());
    thread.start();
  }
}

在这个例子中,我们定义了一个MyRunnable类实现了Runnable接口,并在run()方法中编写了线程的任务逻辑。在主线程中,我们创建了一个Thread对象并将MyRunnable对象作为参数传入,然后调用start()方法来启动线程。

继承Thread类

继承Thread类是Java中创建线程的另一种方法。继承Thread类可以直接重写run()方法,在run()方法中编写线程的任务逻辑。

下面是一个继承Thread类的例子:

class MyThread extends Thread {
  public void run() {
    System.out.println("Hello from MyThread!");
  }
}

public class Main {
  public static void main(String[] args) {
    MyThread thread = new MyThread();
    thread.start();
  }
}

在这个例子中,我们定义了一个MyThread类继承了Thread类,并重写了run()方法,在run()方法中编写了线程的任务逻辑。在主线程中,我们创建了一个MyThread对象并调用start()方法来启动线程。

线程状态

Java线程可以处于不同的状态,状态由Thread.State枚举类型表示。Thread.State枚举类型定义了以下几个状态:

  • NEW:线程对象已创建,但尚未启动。
  • RUNNABLE:线程正在运行或准备运行。
  • BLOCKED:线程正在等待获取一个锁以进入同步代码块。
    -WAITING:线程正在等待另一个线程执行完毕。
  • TIMED_WAITING:线程正在等待另一个线程执行完毕,但等待时间有限。
  • TERMINATED:线程已经执行完毕并结束。

可以通过Thread类的getState()方法获取线程的状态。下面是一个获取线程状态的例子:

Thread thread = new Thread(new MyRunnable());
System.out.println(thread.getState()); // 输出NEW
thread.start();
System.out.println(thread.getState()); // 输出RUNNABLE

在这个例子中,我们创建了一个新的Thread对象并输出了它的状态,此时输出的状态为NEW。然后我们启动线程并再次输出状态,此时输出的状态为RUNNABLE。

线程同步

线程同步是指多个线程协同工作,共同完成任务。线程同步可以通过锁、信号量、条件变量等机制来实现。Java中的线程同步可以通过synchronized关键字和Lock对象来实现。

synchronized关键字

synchronized关键字可以用来修饰代码块或方法,以实现线程同步。当一个线程进入synchronized代码块或方法时,它会获取锁,其他线程需要等待锁释放才能进入代码块或方法。

下面是一个使用synchronized关键字的例子:

class Counter {
  private int count = 0;

  public synchronized void increment() {
    count++;
  }

  public synchronized int getCount() {
    return count;
  }
}

public class Main {
  public static void main(String[] args) throws InterruptedException {
    Counter counter = new Counter();

    Thread t1 = new Thread(() -> {
      for (int i = 0; i < 100000; i++) {
        counter.increment();
      }
    });

    Thread t2 = new Thread(() -> {
      for (int i = 0; i < 100000; i++) {
        counter.increment();
      }
    });

    t1.start();
    t2.start();
    t1.join();
    t2.join();

    System.out.println(counter.getCount()); // 输出200000
  }
}

在这个例子中,我们定义了一个Counter类用于计数,它有一个increment()方法用于增加计数器的值,一个getCount()方法用于获取计数器的值。在这两个方法上我们都使用了synchronized关键字来实现线程同步。

在主线程中,我们创建了两个新的线程t1和t2,它们都调用Counter对象的increment()方法增加计数器的值。由于increment()方法被synchronized关键字修饰,它们会互斥地访问计数器,从而实现了线程同步。

Lock对象

Lock对象是Java中的另一种实现线程同步的机制。Lock对象可以更加灵活地控制锁的获取和释放,相对于synchronized关键字更加底层。

下面是一个使用Lock对象的例子:

class Counter {
  private int count = 0;
  private Lock lock = new ReentrantLock();

  public void increment() {
    lock.lock();
    try {
      count++;
    } finally {
      lock.unlock();
    }
  }

  public int getCount() {
    lock.lock();
    try {
      return count;
    } finally {
      lock.unlock();
    }
  }
}

public class Main {
  public static void main(String[] args) throws InterruptedException {
    Counter counter = new Counter();

    Thread t1 = new Thread(() -> {
      for (int i = 0; i < 100000; i++) {
        counter.increment();
      }
    });

    Thread t2 = new Thread(() -> {
      for (int i = 0; i < 100000; i++) {
        counter.increment();
      }
    });

    t1.start();
    t2.start();
    t1.join();
    t2.join();

    System.out.println(counter.getCount()); // 输出200000
  }
}

在这个例子中,我们定义了一个Counter类用于计数,它有一个increment()方法用于增加计数器的值,一个getCount()方法用于获取计数器的值。在increment()和getCount()方法中,我们使用了Lock对象来实现线程同

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风老魔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值