博客
关于我
21 并发
阅读量:730 次
发布时间:2019-03-21

本文共 5417 字,大约阅读时间需要 18 分钟。

基本线程机制及并发编程

线程在计算机编程中扮演着至关重要的角色。通过创建和管理线程,程序能够同时执行多项任务,提升效率。在本章中,我们将探索线程的基础机制,了解如何在Java中实现任务调度以及如何处理共享资源的竞争与死锁问题。

定义任务

线程可以通过Runnable接口定义任务,实现run()方法即可。Runnable对象可以随时由Thread类或Executor服务运行。例如,LiftOff类通过实现Runnable接口,定义了一个倒计时任务:

class LiftOff implements Runnable {    protected int countDown = 10;    private static int taskCount = 0;    private final int id = taskCount++;    @Override    public void run() {        System.out.println("Thread:" + Thread.currentThread());        while (countDown > 0) {            System.out.println(status());        }    }    private String status() {        return "#" + id + "(" + countDown + ")" + " ";    }}

Thread类

Thread类是Java中线程的核心,它通过构造器接受一个Runnable对象。调用start()方法启动线程运行,自动调用Runnablerun()方法。例如,使用BasicThreads类创建并启动线程:

class BasicThreads {    public static void chapter21_2() {        System.out.println("BasicThreads:" + Thread.currentThread());        Thread t = new Thread(new LiftOff());        t.start();    }}

Executor服务

java.util.concurrent包中,Executor服务提供了更高级的线程管理功能。CachedThreadPool默认创建新的线程执行任务,与FternalThreadSingleThreadExecutor形成了不同策略的选择。

class CachedThreadPool {    public static void chapter21_2() {        System.out.println("CachedThreadPool:" + Thread.currentThread());        ExecutorService executorService = Executors.newCachedThreadPool();        for (int i = 0; i < 3; i++) {            executorService.execute(new LiftOff());        }        executorService.shutdown();    }}

任务返回值

若任务完成后需返回值,可以实现Callable接口。Callable支持异步计算,通过Future获取结果。

class CallableDemo {    public static void chapter21_2() {        ExecutorService executorService = Executors.newCachedThreadPool();        ArrayList
> results = new ArrayList<>(); for (int i = 0; i < 3; i++) { results.add(executorService.submit(new TaskWithResult(i))); } for (Future
fs : results) { try { System.out.println(fs.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } }}

共享资源的竞争与互斥

在多线程环境下,共享资源可能引发竞争,导致逻辑错误。通过synchronize关键字实现方法同步,确保一种线程 一定在执行时占据资源。例如,SynchronizedEvenGenerator确保多个线程仅按顺序访问资源。

abstract class IntGenerator {    public abstract int next();}class SynchronizedEvenGenerator extends IntGenerator {    private int currentValue = 0;    @Override    public synchronized int next() {        currentValue++;        currentValue++;        return currentValue;    }}

Thread中的等待与通知

线程间通过wait()notify()方法进行等待与唤醒。wait()使线程挂起,直到notify()notifyAll()被调用。例如,在WaxOMatic中,WaxOnWaxOff任务通过condition实现等待与唤醒。

class WaxOMatic {    public static void chapter21_5() {        Car car = new Car();        ExecutorService executorService = Executors.newCachedThreadPool();        executorService.execute(new WaxOff(car));        executorService.execute(new WaxOn(car));        try {            TimeUnit.MILLISECONDS.sleep(1000);        } catch (InterruptedException e) {            e.printStackTrace();        }        executorService.shutdownNow();    }}

Deadlock 死锁处理

正確解決哲學家問題,需调整拿取顺序。如FixedDiningPhilosophers,让最后一个哲学家先拿左筷子,解决死锁。

class FixedDiningPhilosophers {    public static void chapter21_6() throws InterruptedException {        int ponder = 3;        int size = 2;        ExecutorService executorService = Executors.newCachedThreadPool();        Chopstick[] chopsticks = new Chopstick[size];        for (int i = 0; i < size; i++) {            Chopstick chopstick = new Chopstick();            Chopsticks[i] = chopstick;        }        for (int i = 0; i < size; i++) {            Runnable run = () -> {                try {                    while (!Thread.interrupted()) {                        right.take();                        left.take();                    }                } catch (InterruptedException e) {                    e.printStackTrace();                }                System.out.println("philosopher " + i + " done");            };            executorService.execute(run);        }        TimeUnit.SECONDS.sleep(3);        for (int i = 0; i < size; i++) {            Chopstick left = Chopsticks[i];            Chopstick right = Chopsticks[(i + 1) % size];            left.drop();            right.drop();        }    }}

性能优化与可扩展性

通过比较LockSynchronized的性能差异,选择合适的互斥机制。同时,利用ConcurrentHashMapCopyOnWriteArrayList等高效容器,确保线程安全与性能并存。

class ConcurrentHashMapExample {    public static void chapter21_9() {        ConcurrentHashMap
map = new ConcurrentHashMap(); map.put("key1", 100); map.put("key2", 200); System.out.println(map.get("key1"));//100 System.out.println(map.size());//2 map Put "key3", 300 map remove"key1", 200 map.get("key1")//200 System.out.println(map.size())//3 }}

未来任务

通过ActiveObjectDemo展示活动对象的特点,实现任务的串行化与资源管理。这种模式允许任务在多线程环境下无缝衔接,提升整体效率。

class ActiveObjectDemo {    private ExecutorService executorService = Executors.newSingleThreadExecutor();    public Future
calculateInt(int x, int y) { return executorService.submit(() -> { System.out.println("starting " + x + " + " + y); try { TimeUnit.MILLISECONDS.sleep(200); return x + y; } catch (InterruptedException e) { e.printStackTrace(); } }); } public void shutdown() { executorService.shutdown(); }}

通过以上方法和实例,可以全面理解线程机制,掌握解决多线程编程问题的关键策略。

转载地址:http://okdgz.baihongyu.com/

你可能感兴趣的文章
pm2通过配置文件部署nodejs代码到服务器
查看>>
PML调用PDMS内核命令研究
查看>>
PMM安装-第一篇
查看>>
PMP知识要点(第九章)
查看>>
PNETLab 镜像包官方下载太慢?不急,最新版本PNET_4.2.10分享!
查看>>
POCO库中文编程参考指南(4)Poco::Net::IPAddress
查看>>
Quartz基本使用(二)
查看>>
POC项目安装与使用指南
查看>>
Podman核心技术详解
查看>>
pods 终端安装 第三方框架的一些命令
查看>>
Podzielno
查看>>
PoE、PoE+、PoE++ 三款交换机如何选择?一文带你了解
查看>>
PoE三种标准:标准 PoE、PoE+、PoE++,网络工程师必知!
查看>>
POI 的使用
查看>>
poi 读取单元格为null者空字符串
查看>>
poi-tl简介与文本/表格和图片渲染
查看>>
pointnet分割自己的点云数据_PointNet解析
查看>>
POI实现Excel导入Cannot get a text value from a numeric cell
查看>>
POI实现Excel导入时提示NoSuchMethodError: org.apache.poi.util.POILogger.log
查看>>
POI实现Excel导出时常用方法说明
查看>>