欢迎访问宙启技术站
智能推送

Java多线程编程中的常用函数总结

发布时间:2023-05-29 03:24:08

Java多线程编程是实现高并发的基础,为了编写高效的多线程程序,需要掌握一些常用的多线程函数。本文将对Java多线程编程中的一些常用函数进行总结,涵盖线程的创建、互斥与同步、线程通信、线程状态控制等几个方面。

### 线程的创建、启动与终止

#### 创建线程

Java提供了两种创建线程的方式:继承Thread类和实现Runnable接口。其中,实现Runnable接口具有更好的扩展性和代码复用性,因为Java不支持多重继承,而实现接口可以避免这个问题。

// 通过继承Thread类创建线程
public class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("MyThread is running");
    }
}

// 通过实现Runnable接口创建线程
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("MyRunnable is running");
    }
}

public static void main(String[] args) {
    // 创建线程
    MyThread myThread = new MyThread();
    MyRunnable myRunnable = new MyRunnable();

    // 启动线程
    myThread.start();
    new Thread(myRunnable).start();
}

#### 启动线程

线程创建后必须调用start()方法才能启动线程。start()方法会自动调用run()方法,启动新线程,使其进入就绪状态。不能直接调用run()方法,这样虽然会执行run()方法中的代码,但并不会创建新线程,只是在当前线程上运行run()方法的代码而已。

// 启动线程
myThread.start();
new Thread(myRunnable).start();

#### 线程的终止

Java提供了四种方式来终止线程:正常退出、使用标志变量、使用Interrupt()方法、使用stop()方法。其中,使用stop()方法已经被弃用,不再推荐使用。

正常退出是指在run()方法中执行完所有的语句后自动结束线程。使用标志变量可以使线程在正常退出前结束循环,这是一种比较安全的线程终止方法。使用Interrupt()方法可以中断线程的阻塞状态,使其进入就绪状态。在run()方法中需要对InterruptedException异常进行处理。在使用Interrupt()方法时需要注意,如果线程处于正常运行状态,调用Interrupt()方法并不会使线程立即退出,而是将线程标记为需要中断,并在有机会退出时退出。使用Interrupt()方法可以中断线程睡眠、等待、输入输出等操作。

// 正常退出
public class MyThread extends Thread {
    @Override
    public void run() {
        // run方法中执行代码
    }
}

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

// 使用标志变量
public class MyThread extends Thread {
    private volatile boolean flag = true;

    public void stopThread() {
        flag = false;
    }

    @Override
    public void run() {
        while (flag) {
            // run方法中执行代码
        }
    }
}

MyThread myThread = new MyThread();
myThread.start();
myThread.stopThread();

// 使用Interrupt()方法
public class MyThread extends Thread {
    @Override
    public void run() {
        try {
            while (!isInterrupted()) {
                // run方法中执行代码
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

MyThread myThread = new MyThread();
myThread.start();
myThread.interrupt();

### 线程的互斥与同步

多线程程序中,如果多个线程同时访问共享资源,可能会出现数据不一致的情况。在Java多线程编程中,可以使用synchronized关键字对代码块或方法进行加锁,以保证多个线程访问共享资源时的互斥性和同步性。

#### synchronized关键字

synchronized关键字可以用来修饰代码块和方法。当某个线程进入synchronized代码块或方法时,会将锁标记为已占用,其他线程必须等待该线程释放锁后才能进入synchronized代码块或方法。

// 代码块同步
public void subtractOne() {
    synchronized (this) {
        if (count > 0) {
            count--;
        }
    }
}

// 方法同步
public synchronized void subtractTwo() {
    if (count > 0) {
        count--;
    }
}

#### Lock接口

除了使用synchronized关键字实现线程同步,还可以使用Lock接口及其实现类ReentrantLock来实现线程互斥和同步。Lock提供了比synchronized更多的功能,比如可以设置超时时间、尝试获取锁等。

Lock lock = new ReentrantLock();
lock.lock();
try {
    // 需要同步的代码块
} finally {
    lock.unlock();
}

### 线程通信

Java提供了wait()、notify()和notifyAll()这三个方法来实现线程通信。这三个方法必须在synchronized代码块中调用,否则会抛出IllegalMonitorStateException异常。

#### wait()方法

wait()方法会使当前线程进入等待状态,直到其他线程调用notify()或notifyAll()方法将其唤醒。在调用wait()方法时,必须持有对象的锁,否则会抛出IllegalMonitorStateException异常。wait()方法会释放持有的锁,以允许其他线程访问同步块。

synchronized (obj) {
    while (condition != true) {
        obj.wait();
    }
    // 执行操作
}

#### notify()方法

notify()方法用于唤醒一个等待中的线程,如果有多个线程在等待,则随机唤醒其中一个线程。在调用notify()方法时,必须持有对象的锁,否则会抛出IllegalMonitorStateException异常。

synchronized (obj) {
    condition = true;
    obj.notify();
}

#### notifyAll()方法

notifyAll()方法用于唤醒所有等待中的线程,每个线程都可以进行竞争执行。在调用notifyAll()方法时,必须持有对象的锁,否则会抛出IllegalMonitorStateException异常。

synchronized (obj) {
    condition = true;
    obj.notifyAll();
}

### 线程状态控制

Java多线程编程中,可以使用Thread类的一些方法控制线程状态。

#### Thread.sleep()方法

Thread.sleep()方法可以使线程进入睡眠状态,时间到后自动唤醒。在调用sleep()方法时,不需要持有锁,但是可能会抛出InterruptedException异常,需要进行异常处理。

try {
    // 线程睡眠100毫秒
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}

#### Thread.yield()方法

Thread.yield()方法可以使线程放弃当前使用的CPU资源,让其他线程继续执行。调用yield()方法并不会将线程转移到就绪状态,而是仅仅让线程进入可运行状态,等待获取CPU资源。

Thread.yield();

#### Thread.join()方法

Thread.join()方法可以使当前线程等待其他线程执行完毕,再继续执行。在调用join()方法时,需要先将其他线程创建并启动,然后再调用join()方法等待其他线程执行完毕。

`java

Thread threadOne = new Thread(() -> {

// 线程One的代码

});

Thread threadTwo = new Thread(() -> {

// 线程Two的代码

});

threadOne.start();