当前位置: 首页 > news >正文

JAVA中的线程控制

线程控制是Java并发编程中的核心内容,涉及到线程的创建、同步、通信、调度等多个方面。

一、线程创建与启动 在Java中,创建线程有两种方式:

继承Thread类和实现Runnable接口。

  1. 继承Thread类 代码例子:

// 继承Thread类
class MyThread extends Thread {@Overridepublic void run() {// 线程执行体System.out.println("线程正在执行");}
}
public class Main {public static void main(String[] args) {MyThread myThread = new MyThread(); // 创建线程对象myThread.start(); // 启动线程}
}
  1. 实现Runnable接口 代码例子:

// 实现Runnable接口
class MyRunnable implements Runnable {@Overridepublic void run() {// 线程执行体System.out.println("线程正在执行");}
}
public class Main {public static void main(String[] args) {Thread thread = new Thread(new MyRunnable()); // 创建线程对象thread.start(); // 启动线程}
}

二、线程同步

当多个线程访问同一资源时,可能会出现线程安全问题。为了解决这个问题,Java提供了同步机制。

  1. 使用synchronized关键字 代码例子:

class Counter {private int count = 0;// 同步方法public synchronized void increment() {count++;}public int getCount() {return count;}
}
public class Main {public static void main(String[] args) {Counter counter = new Counter();Thread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {counter.increment();}});t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("计数器最终结果:" + counter.getCount());}
}
  1. 使用Lock接口 代码例子:

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Counter {private int count = 0;private Lock lock = new ReentrantLock();public void increment() {lock.lock(); // 加锁try {count++;} finally {lock.unlock(); // 解锁}}public int getCount() {return count;}
}
// 线程控制逻辑与上一个例子类似,此处不再赘述

三、线程通信

线程通信主要涉及到wait()、notify()和notifyAll()这三个方法。 代码例子:

class ProducerConsumer {private int product = 0;private boolean isEmpty = true;public synchronized void produce() {while (!isEmpty) {try {wait(); // 等待消费者消费} catch (InterruptedException e) {e.printStackTrace();}}product++;System.out.println("生产者生产了产品:" + product);isEmpty = false;notifyAll(); // 通知消费者}public synchronized void consume() {while (isEmpty) {try {wait(); // 等待生产者生产} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("消费者消费了产品:" + product);isEmpty = true;notifyAll(); // 通知生产者}
}
public class Main {public static void main(String[] args) {ProducerConsumer pc = new ProducerConsumer();Thread producer = new Thread(() -> {for (int i = 0; i < 10; i++) {pc.produce();}});Thread consumer = new Thread(() -> {for (int i = 0; i < 10; i++) {pc.consume();}});producer.start();consumer.start();}
}

四、线程调度

Java提供了线程调度器来控制线程的执行顺序。

  1. 设置线程优先级 代码例子:

Thread t1 = new Thread(() -> {// 线程执行体
});
t1.setPriority(Thread.MAX_PRIORITY); // 设置线程优先级为最高
Thread t2 = new Thread(() -> {// 线程执行体
});t2.setPriority(Thread.MIN_PRIORITY); // 设置线程优先级为最低
t1.start();
t2.start();
  1. 使用线程池 线程池可以有效地管理和控制线程的创建和销毁,提高系统性能。 代码例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(5);// 提交任务到线程池for (int i = 0; i < 10; i++) {executorService.execute(() -> {// 线程执行体System.out.println("线程池中的线程正在执行:" + Thread.currentThread().getName());});}// 关闭线程池executorService.shutdown();}
}

五、线程中断

线程中断是一种协作机制,用于通知线程中断其正在执行的任务。 代码例子:

class MyRunnable implements Runnable {@Overridepublic void run() {while (!Thread.currentThread().isInterrupted()) {// 执行任务System.out.println("线程正在执行任务");try {Thread.sleep(1000); // 模拟耗时操作} catch (InterruptedException e) {// 捕获中断异常,并设置中断标志Thread.currentThread().interrupt();e.printStackTrace();}}System.out.println("线程被中断,退出任务");}
}
public class Main {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(new MyRunnable());thread.start();// 主线程休眠一段时间后中断子线程Thread.sleep(3000);thread.interrupt();}
}

六、线程局部变量

ThreadLocal类可以创建线程局部变量,确保每个线程都有自己独立的变量副本。

代码例子:

import java.util.concurrent.atomic.AtomicInteger;
public class Main {// 创建线程局部变量private static final ThreadLocal<Integer> threadLocalValue = new ThreadLocal<Integer>() {@Overrideprotected Integer initialValue() {return new AtomicInteger().incrementAndGet();}};public static void main(String[] args) {// 在不同线程中访问线程局部变量Thread t1 = new Thread(() -> {System.out.println("线程1的局部变量值:" + threadLocalValue.get());});Thread t2 = new Thread(() -> {System.out.println("线程2的局部变量值:" + threadLocalValue.get());});t1.start();t2.start();}
}

七、总结

通过这些机制,我们可以更好地管理和控制线程的执行,编写出高效、稳定的并发程序。


http://www.mrgr.cn/news/46992.html

相关文章:

  • EFCore HasDefaultValueSql
  • ThreeJs练习——载入外部模型
  • Selenium 进行网页自动化操作的一个示例,绕过一些网站的自动化检测。python编程
  • Java面试总结(1)
  • 《AI模型格局演变:Claude、Gemini Flash与OpenAI的技术角力》
  • Redis常见
  • 画质修复怎么弄?这4个恢复照片清晰度的修复工具快收藏
  • vue3学习记录-watch
  • 智慧水利(数字孪生流域)建设方案
  • 从不同的细节察觉人的性格
  • A股热了,但黄金周实体经济的统计数字却有点凉
  • 地理空间数据共享资源,爱好者进
  • PELCO-D协议简介
  • python 实现双向A*算法
  • vue3实现登录获取token并自动刷新token进行JWT认证
  • 面试指南1009
  • mysql模糊查询优化
  • 数通--3
  • linux通过网络scp传文件
  • 2024最新版:大厂AI大模型面试题集锦及详解,非常详细收藏我这一篇就够了
  • 仿IOS桌面悬浮球(支持拖拽、自动吸附、自动改变透明度与点击、兼容PC端与移动端)
  • Umi中的微前端
  • 如何做好乡村文化传承与乡村经济发展
  • mmap和ioremmap解析
  • 揭秘地表水与地下水耦合的奥秘!基于QSWATMOD的SWAT-MODFLOW模拟
  • centos6.9不用安装光盘在控制台重置root密码