三则案例,助你掌握多线程 | 带你学《Java语言高级特性》之十五

简介: 经历了前几节的学习,相信你已经对多线程有了自己的见解,现在,跟作者一起实操三则案例,助你快速消化所学知识吧!

上一篇:另类的“同步”-volatile关键字 | 带你学《Java语言高级特性》之十四
【本节目标】
通过阅读本节内容,你将通过数字加减、生产电脑、竞争抢答三则案例的多线程相关逻辑实现,进一步掌握多线程开发的相关能力,对线程的各类操作更加得心应手。

多线程案例分析一:数字加减

设计4个线程对象,两个线程执行减操作,两个线程执行加操作。

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Resource res = new Resource();
        SubThread st = new SubThread(res);
        AddThread at = new AddThread(res);
        new Thread(at, "加法线程-A ").start();
        new Thread(at, "加法线程-B ").start();
        new Thread(st, "减法线程-X ").start();
        new Thread(st, "减法线程-Y ").start();
    }
}
class AddThread implements Runnable {
    private Resource resource;
    public AddThread(Resource resource) {
        this.resource = resource;
    }
    @Override
    public void run() {
        for (int x = 0 ; x< 50 ; x++) {
            try {
                this.resource.add();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
class SubThread implements Runnable {
    private Resource resource;
    public SubThread(Resource resource) {
        this.resource = resource;
    }
    @Override
    public void run() {
        for (int x = 0 ; x < 50 ; x++) {
            try {
                this.resource.sub();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
class Resource {     //定义一个操作的资源
    private int num = 0;      //这个是要进行加减操作的数据
    private boolean flag = true;       //加减的切换
    //flag = true:表示可以进行加法操作,但是无法进行减法操作
    //flag = false:表示可以进行减法操作,但是无法进行加法操作
    public synchronized void add() throws Exception {      //执行加法操作
        if (this.flag == false) {         //现在需要执行的是减法操作,加法操作要等待
            super.wait();
        }
        Thread.sleep(100) ;
        this.num++ ;
        System.out.println("【加法操作 -" + Thread.currentThread().getName() + "】num = " + this.num) ;
        this.flag = false ;    //加法操作执行完毕,需要执行减法处理
        super.notifyAll() ;   //唤醒全部等待线程

    }
    public synchronized void sub() throws Exception {    //执行减法操作
        if (this.flag == true) {      //减法操作需要等待
            System.out.println("【减法操作 -" + 
Thread.currentThread().getName() + "】进行等待") ;
            super.wait() ;
        }
        Thread.sleep(200) ;
        this.num-- ;
        System.out.println("【减法操作 -" + Thread.currentThread().getName() + "】num = " + this.num) ;
        this.flag = true ;
        super.notifyAll() ;
    }
}

image.png
图一 多线程加减法操作

这是一个经典的多线程开发操作,这一个程序里面一定要考虑的核心本质在于:加一个、减一个,整体的计算结果应该在0、-1、1 中循环出现才是合理的。

多线程案例分析二:生产电脑

设计一个生产电脑和搬运电脑类,要求生产出一台电脑就搬走一台电脑,如果没有新的电脑生产出来,则搬运工需要等待新电脑产出;如果生产出的电脑没有搬走,则要等待电脑搬走再生产,并统计出生产的电脑数量。
在本程序中,就是一个标准的生产者与消费者的处理模型,那么下面实现具体的程序代码。

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Resource res = new Resource() ;
        new Thread(new Producer(res)).start() ;
        new Thread(new Consumer(res)).start() ;
        new Thread(st).start() ;
        new Thread(st).start() ;
    }
}
class Producer implements Runnable {
    private Resource resource ;
    public Producer(Resource resource) {
        this.resource = resource ;
    }
    @Override
    public void run() {
        for (int x = 0; x < 50; x++) {
            try {
                this.resource.make() ;
            } catch (Exception e) {
                e.printStackTrace() ;
            }
        }
    }
}
class Consumer implements Runnable {
    private Resource resource ;
    public Consumer(Resource resource) {
        this.resource = resource ;
    }
    @Override
    public void run() {
        for (int x = 0 ; x < 50 ; x++) {
            try {
                this.resource.get() ;
            } catch (Exception e) {
                e.printStackTrace() ;
            }
        }
    }
}
class Resource {
    private Computer computer ;
    private boolean flag = true ;         //标记
    public synchronized void make() throws Exception {
        if (this.computer != null) {   //已经生产过了
            super.wait() ;
        }
        Thread.sleep(100) ;
        this.computer = new Computer("MLDN牌电脑", 1.1) ;
        System.out.println("【生产电脑】"+ this.computer) ;
        super.notifyAll() ;
    }
    public synchronized void get() throws Exception {
        if (this.computer == null) {    //没有生产过
            super.wait() ;
        }
        Thread.sleep(10) ;
        System.out.println("【取走电脑】"+ this.computer) ;
        this.computer = null ;    //已经取走了
        super.notifyAll() ;
    }
}
class Computer {
    private static int count = 0 ;    //表示生产的个数
    private String name ;
    private double price ;
    public Computer(String name, double price) {
        this.name = name ;
        this.price = price ;
        count++ ;
    }
    public String toString() {
        return "【第" + count + "台电脑】电脑名字:" + this.name + "价值:" + this.price ;
    }
}

image.png
图二 实现生产电脑

多线程案例分析三:竞争抢答

实现一个竞拍抢答程序:要求设置三个抢答者(三个线程),而后同时发出抢答指令,抢答成功者给出成功提示,未抢答成功者给出失败提示。

对于这个多线程操作,由于里面需要牵扯到数据返回问题,那么现在最好使用Callable是比较方便的一种处理形式。

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        MyThread mt = new MyThread();
        FutureTask<String> taskA = new FutureTask(mt);
        FutureTask<String> taskB = new FutureTask(mt);
        FutureTask<String> taskC = new FutureTask(mt);
        new Thread(taskA, "竞赛者A").start();
        new Thread(taskB, "竞赛者B").start();
        new Thread(taskC, "竞赛者C").start();
        System.out.println(taskA.get());
        System.out.println(taskB.get());
        System.out.println(taskC.get());
    }
}
class MyThread implements Callable<String> {
    private boolean flag = false;          //抢到处理
    @Override
    public String call() throws Exception {
        synchronized (this) {                //数据同步
            if (this.flag == false) {        //抢答成功
                this.flag = true;
                return Thread.currentThread().getName() + "抢答成功!" ;
            } else {
                return Thread.currentThread().getName() + "抢答失败!" ;
            }
        }
    }
}

image.png
图三 多线程竞答

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:让String拥有变化之力 | 带你学《Java语言高级特性》之十六
更多Java面向对象编程文章查看此处

相关文章
|
21天前
|
数据采集 存储 弹性计算
高并发Java爬虫的瓶颈分析与动态线程优化方案
高并发Java爬虫的瓶颈分析与动态线程优化方案
Java 数据库 Spring
59 0
|
1月前
|
算法 Java
Java多线程编程:实现线程间数据共享机制
以上就是Java中几种主要处理多线程序列化资源以及协调各自独立运行但需相互配合以完成任务threads 的技术手段与策略。正确应用上述技术将大大增强你程序稳定性与效率同时也降低bug出现率因此深刻理解每项技术背后理论至关重要.
88 16
|
2月前
|
缓存 并行计算 安全
关于Java多线程详解
本文深入讲解Java多线程编程,涵盖基础概念、线程创建与管理、同步机制、并发工具类、线程池、线程安全集合、实战案例及常见问题解决方案,助你掌握高性能并发编程技巧,应对多线程开发中的挑战。
|
2月前
|
数据采集 存储 前端开发
Java爬虫性能优化:多线程抓取JSP动态数据实践
Java爬虫性能优化:多线程抓取JSP动态数据实践
|
3月前
|
安全 Java API
Java 集合高级应用与实战技巧之高效运用方法及实战案例解析
本课程深入讲解Java集合的高级应用与实战技巧,涵盖Stream API、并行处理、Optional类、现代化Map操作、不可变集合、异步处理及高级排序等核心内容,结合丰富示例,助你掌握Java集合的高效运用,提升代码质量与开发效率。
209 0
|
3月前
|
安全 JavaScript Java
java Web 项目完整案例实操指南包含从搭建到部署的详细步骤及热门长尾关键词解析的实操指南
本项目为一个完整的JavaWeb应用案例,采用Spring Boot 3、Vue 3、MySQL、Redis等最新技术栈,涵盖前后端分离架构设计、RESTful API开发、JWT安全认证、Docker容器化部署等内容,适合掌握企业级Web项目全流程开发与部署。
158 0
|
3月前
|
Java API 调度
从阻塞到畅通:Java虚拟线程开启并发新纪元
从阻塞到畅通:Java虚拟线程开启并发新纪元
308 83
|
3月前
|
安全 算法 Java
Java 多线程:线程安全与同步控制的深度解析
本文介绍了 Java 多线程开发的关键技术,涵盖线程的创建与启动、线程安全问题及其解决方案,包括 synchronized 关键字、原子类和线程间通信机制。通过示例代码讲解了多线程编程中的常见问题与优化方法,帮助开发者提升程序性能与稳定性。
145 0
|
3月前
|
JSON JavaScript 前端开发
Python+JAVA+PHP语言,苏宁商品详情API
调用苏宁商品详情API,可通过HTTP/HTTPS发送请求并解析响应数据,支持多种编程语言,如JavaScript、Java、PHP、C#、Ruby等。核心步骤包括构造请求URL、发送GET/POST请求及解析JSON/XML响应。不同语言示例展示了如何获取商品名称与价格等信息,实际使用时请参考苏宁开放平台最新文档以确保兼容性。