Java多线程编程:Thread与Runnable的并发控制

Thread与Runnable的基本区别

Thread是Java中表示线程的类,直接继承Thread类并重写run方法即可创建线程。Runnable是一个接口,需要实现run方法,并通过Thread类的构造函数传入Runnable实例来创建线程。

继承Thread类的方式简单直接,但Java不支持多重继承,限制了扩展性。实现Runnable接口更灵活,允许类继承其他类,同时实现多线程功能。

线程创建与启动

继承Thread类的方式:

java 复制代码
class MyThread extends Thread {
    public void run() {
        System.out.println("Thread running");
    }
}
MyThread t = new MyThread();
t.start();

实现Runnable接口的方式:

java 复制代码
class MyRunnable implements Runnable {
    public void run() {
        System.out.println("Runnable running");
    }
}
Thread t = new Thread(new MyRunnable());
t.start();

并发控制机制

synchronized关键字用于实现线程同步,可以修饰方法或代码块。修饰实例方法时,锁是当前实例对象;修饰静态方法时,锁是当前类的Class对象。

实例方法同步:

java 复制代码
public synchronized void increment() {
    count++;
}

代码块同步:

java 复制代码
public void increment() {
    synchronized(this) {
        count++;
    }
}

线程安全的数据结构

Java并发包提供了多种线程安全的集合类,如ConcurrentHashMap、CopyOnWriteArrayList等。这些类通过不同的并发策略实现了高性能的线程安全。

使用ConcurrentHashMap示例:

java 复制代码
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("key", 1);

线程间通信

wait()、notify()和notifyAll()方法用于线程间通信,必须在同步代码块或方法中使用。wait()使当前线程等待,释放锁;notify()唤醒一个等待线程。

生产者消费者示例:

java 复制代码
public synchronized void produce() throws InterruptedException {
    while (queue.size() == MAX) {
        wait();
    }
    queue.add(item);
    notifyAll();
}

public synchronized void consume() throws InterruptedException {
    while (queue.isEmpty()) {
        wait();
    }
    queue.remove();
    notifyAll();
}

线程池的使用

Executor框架提供了线程池管理功能,可以重用线程,减少创建和销毁线程的开销。常见的线程池类型包括FixedThreadPool、CachedThreadPool等。

创建固定大小线程池:

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/sheng.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/sheng878.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/kol44.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/niux.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/dijiu.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/liu.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/iuijd.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/chang.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/jiu.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/cood.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/les.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/gouh.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/daijiji.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/wuan.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/fou.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/gudeng.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/ali.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/jiuang.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/wanwan.md

gitee.com/sadsadasdwe2/wvgreuxr/blob/master/chuang.md

java 复制代码
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> {
    System.out.println("Task running");
});
executor.shutdown();

原子操作类

java.util.concurrent.atomic包提供了原子操作类,如AtomicInteger、AtomicLong等。这些类通过CAS(Compare-And-Swap)操作实现无锁线程安全。

使用AtomicInteger示例:

java 复制代码
AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();
相关推荐
xieliyu.14 小时前
Java算法精讲:双指针(三)
java·开发语言·算法
love530love14 小时前
LiveTalking 数字人项目 Windows 部署完全指南(EPGF 架构)
人工智能·windows·python·架构·livetalking·epgf
遇事不決洛必達14 小时前
【Python基础】GIL 锁是什么及其对爬虫的影响
爬虫·python·线程·进程·gil锁
明夜之约14 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee14 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Jinkxs14 小时前
Resilience4j- 与 Spring Boot 快速集成:自动配置与基础注解使用
java·spring boot·后端
辣机小司14 小时前
【踩坑记录:Spring Boot 配置文件读取值不一致?警惕 YAML 的“八进制陷阱”与 SnakeYAML 版本之谜】
java·spring boot·后端·yaml·踩坑记录
CryptoPP15 小时前
快速对接东京证券交易所API数据:实战指南与代码示例
开发语言·人工智能·windows·python·信息可视化·区块链
ZC跨境爬虫15 小时前
跟着 MDN 学JavaScript day_7:数学运算与逻辑判断实战测试
开发语言·前端·javascript·学习·ecmascript
fangdengfu12315 小时前
ES分析系统各个服务日志占用量
java·前端·elasticsearch