Java多线程 | 操作线程的方法详解

文章目录

    • 一、线程的启动
      • [1.1 start()方法](#1.1 start()方法)
    • 二、线程的休眠与中断
      • [2.1 Thread.sleep()方法](#2.1 Thread.sleep()方法)
      • [2.2 interrupt()方法](#2.2 interrupt()方法)
    • 三、线程的等待与唤醒
      • [3.1 wait()方法](#3.1 wait()方法)
      • [3.2 Object类的notify()和notifyAll()方法](#3.2 Object类的notify()和notifyAll()方法)
      • [3.3 await()和signal()方法](#3.3 await()和signal()方法)
      • [3.4 使用join()方法等待线程执行完成](#3.4 使用join()方法等待线程执行完成)
    • 四、线程的状态控制与管理
      • [4.1 线程的优先级设置](#4.1 线程的优先级设置)
      • [4.2 线程的守护与非守护状态](#4.2 线程的守护与非守护状态)
    • 五、其他常用的线程操作方法
      • [5.1 使用yield()方法让出CPU资源](#5.1 使用yield()方法让出CPU资源)
      • [5.2 使用isAlive()方法判断线程是否存活](#5.2 使用isAlive()方法判断线程是否存活)

一、线程的启动

1.1 start()方法

无论是通过继承Thread类还是实现Runnable接口,线程的启动都需要调用start()方法。

java 复制代码
// 定义一个实现Runnable接口的自定义线程类
public class MyRunnable implements Runnable {
    @Override
    public void run() {
        // 线程执行的代码逻辑
    }
}

// 在主线程中创建并启动自定义线程
public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread = new Thread(new MyRunnable());
        // 启动线程
        thread.start();
    }
}

二、线程的休眠与中断

2.1 Thread.sleep()方法

Thread.sleep()方法用于使当前线程休眠一段时间。它接受一个以毫秒为单位的参数,表示线程休眠的时间,调用这个方法必须要声明或捕捉异常。

java 复制代码
        try {
            // 线程休眠2秒
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("线程休眠结束");

2.2 interrupt()方法

Thread类的interrupt()方法用于中断线程。当一个线程被中断时,它的中断状态将被设置为true(默认是 flase),设置后不一定真的中断,看jvm如何选择,我们把握不了。

调用中断方法也要声明或捕捉异常:InterruptedException

可以通过Thread类的isInterrupted()方法来检查线程的中断状态。

java 复制代码
public class MyThread implements Runnable {
    @Override
    public void run() {
        while (!Thread.currentThread().isInterrupted()) {
            System.out.println("线程执行中");
        }
        System.out.println("线程被中断");
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread = new Thread(new MyThread());
        // 启动线程
        thread.start();
        // 中断子线程
        try {
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

三、线程的等待与唤醒

线程的等待与唤醒是多线程编程中常用的一种机制,它允许线程在满足特定条件之前等待,然后在条件满足时被唤醒继续执行。Java提供了多种方式来实现线程的等待与唤醒。

3.1 wait()方法

Object类中的wait()方法用于使当前线程等待,并释放当前线程持有的锁。wait()方法需要在synchronized块内部调用,以确保线程在等待前释放锁。

调用wait方法使线程进入等到状态后,不会自动醒过来,需要手动让线程苏醒。

java 复制代码
public class MyThread implements Runnable {
   final Object lock = new Object(); // 用于同步的对象
    
    @Override
    public void run() {
        synchronized (lock) {
            // 线程等待,并释放锁
            lock.wait();
        }
    }
}

3.2 Object类的notify()和notifyAll()方法

Object类中的notify()方法用于唤醒在相同对象上调用wait()方法而等待的单个线程,而notifyAll()方法用于唤醒所有在相同对象上调用wait()方法而等待的线程。

java 复制代码
public class MyThread implements Runnable {
    private final Object lock;
    
    public MyThread(Object lock) {
        this.lock = lock;
    }
    
    @Override
    public void run() {
        synchronized (lock) {
            try {
                // 线程等待,并释放锁
                lock.wait();
                // 线程被唤醒后执行其他操作
                System.out.println("线程被唤醒");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Object lock = new Object();
        // 创建自定义线程对象
        MyThread myThread1 = new MyThread(lock);
        MyThread myThread2 = new MyThread(lock);
        // 创建线程对象
        Thread thread1 = new Thread(myThread1);
        Thread thread2 = new Thread(myThread2);
        // 启动线程
        thread1.start();
        thread2.start();
        
        // 主线程休眠1秒后唤醒所有子线程
        try {
            Thread.sleep(1000);
            synchronized (lock) {
                lock.notifyAll();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.3 await()和signal()方法

Condition接口的await()方法可以使线程等待,并释放当前线程持有的锁。当其他线程调用signal()或signalAll()方法时,等待的线程将被唤醒。

java 复制代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MyThread implements Runnable {
    private final Lock lock;
    private final Condition condition;
    
    public MyThread(Lock lock, Condition condition) {
        this.lock = lock;
        this.condition = condition;
    }
    
    @Override
    public void run() {
        lock.lock();
        try {
            // 线程等待,并释放锁
            condition.await();
            // 线程被唤醒后执行其他操作
            System.out.println("线程被唤醒");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        // 创建自定义线程对象
        MyThread myThread = new MyThread(lock, condition);
        // 创建线程对象
        Thread thread = new Thread(myThread);
        // 启动线程
        thread.start();
        
        // 主线程休眠1秒后唤醒子线程
        try {
            Thread.sleep(1000);
            lock.lock();
            condition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

3.4 使用join()方法等待线程执行完成

join()方法可以使一个线程等待另一个线程执行完成。当调用线程的join()方法时,调用线程将被阻塞,直到被调用的线程执行完成。下面是使用join()方法等待线程执行完成的示例:

java 复制代码
public class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println("子线程开始执行");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("子线程执行完成");
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建自定义线程对象
        MyThread myThread = new MyThread();
        // 创建线程对象
        Thread thread = new Thread(myThread);
        // 启动线程
        thread.start();
        
        // 主线程调用join()方法等待子线程执行完成
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println("主线程继续执行");
    }
}

四、线程的状态控制与管理

4.1 线程的优先级设置

线程的优先级用于指定线程在竞争CPU资源时的相对重要性。Java中使用整数表示线程的优先级,范围从1到10,其中1为最低优先级,10为最高优先级。可以使用setPriority()方法设置线程的优先级,使用getPriority()方法获取线程的优先级。

注意:设置了高的优先级只是让线程获取资源的概率增大。

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread = new Thread(() -> {
            System.out.println("线程执行中");
        });
        
        // 设置线程优先级为最高
        thread.setPriority(Thread.MAX_PRIORITY);
        
        // 获取线程优先级
        int priority = thread.getPriority();
        System.out.println("线程优先级:" + priority);
        
        // 启动线程
        thread.start();
    }
}

4.2 线程的守护与非守护状态

线程可以分为守护线程和非守护线程。当只剩下守护线程运行时,JVM会退出。可以使用setDaemon()方法将线程设置为守护线程,使用isDaemon()方法判断线程是否为守护线程。

守护线程的优先级低,这是因为守护线程的业务是不紧急的,像JVM垃圾回收线程就被设置成了守护线程。

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread = new Thread(() -> {
            System.out.println("线程执行中");
        });
        
        // 设置线程为守护线程
        thread.setDaemon(true);
        
        // 判断线程是否为守护线程
        boolean isDaemon = thread.isDaemon();
        System.out.println("线程是否为守护线程:" + isDaemon);
        
        // 启动线程
        thread.start();
    }
}

五、其他常用的线程操作方法

5.1 使用yield()方法让出CPU资源

yield()方法是一个静态方法,用于提示线程调度器将当前线程让出CPU资源,使得其他具有相同优先级的线程有机会执行。调用yield()方法后,当前线程会从运行状态变为就绪状态,然后等待线程调度器重新调度。

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread1 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程1执行中");
                Thread.yield();
            }
        });

        Thread thread2 = new Thread(() -> {
            for (int i = 0; i < 5; i++) {
                System.out.println("线程2执行中");
                Thread.yield();
            }
        });

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

在上面的示例中,创建了两个线程对象thread1thread2,它们分别输出"线程1执行中"和"线程2执行中"。在每次循环中,通过调用yield()方法让出CPU资源,使得两个线程可以交替执行。

5.2 使用isAlive()方法判断线程是否存活

isAlive()方法用于判断线程是否存活,即线程是否已经启动且尚未终止。如果线程存活返回true,否则返回false

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 创建线程对象
        Thread thread = new Thread(() -> {
            System.out.println("线程执行中");
        });

        // 启动线程
        thread.start();

        // 判断线程是否存活
        boolean isAlive = thread.isAlive();
        System.out.println("线程是否存活:" + isAlive);
    }
}
相关推荐
学步_技术3 分钟前
Python编码系列—Python抽象工厂模式:构建复杂对象家族的蓝图
开发语言·python·抽象工厂模式
【D'accumulation】17 分钟前
典型的MVC设计模式:使用JSP和JavaBean相结合的方式来动态生成网页内容典型的MVC设计模式
java·设计模式·mvc
wn53127 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
试行32 分钟前
Android实现自定义下拉列表绑定数据
android·java
茜茜西西CeCe38 分钟前
移动技术开发:简单计算器界面
java·gitee·安卓·android-studio·移动技术开发·原生安卓开发
Hello-Mr.Wang39 分钟前
vue3中开发引导页的方法
开发语言·前端·javascript
救救孩子把42 分钟前
Java基础之IO流
java·开发语言
WG_1743 分钟前
C++多态
开发语言·c++·面试
小菜yh44 分钟前
关于Redis
java·数据库·spring boot·redis·spring·缓存
宇卿.1 小时前
Java键盘输入语句
java·开发语言