Java web 开发涉及多线程和锁定的应用场景有哪些?(邮件发送和接收示例)

简介: Java web 开发中,有一些场景需要用到多线程和锁定,以提高性能、保证数据一致性或实现特定的功能,多线程和锁定提升网站性能、保障数据安全或实现复杂功能的重要技术手段。

{E0AD6CBA-E530-B12D-9A99-499D8F796559}.pngJava web 开发中,有一些场景需要用到多线程和锁定,以提高性能、保证数据一致性或实现特定的功能,多线程和锁定提升网站性能、保障数据安全或实现复杂功能的重要技术手段。以下是一些常见的应用场景:

  • 异步处理:为了避免耗时操作阻塞主线程或消耗过多资源,可以利用多线程技术异步执行这些操作,如发送邮件、调用外部接口、生成报告等。Java提供了ExecutorService、CompletableFuture等工具类来管理线程池,并通过Future、Callback等方式来获取异步结果。
  • 并发访问共享资源:当多个线程同时访问同一个共享资源,如数据库、文件、缓存等,就需要使用锁定技术来确保数据的一致性和完整性。Java提供了synchronized关键字和Lock接口(如ReentrantLock)来实现锁定机制,并要注意避免死锁、活锁、饥饿等问题。
  • 读写分离:当一个共享资源的读操作远远多于写操作,且写操作不影响读操作的正确性时,可以使用读写分离技术来提高并发性能。Java提供了ReadWriteLock接口(如ReentrantReadWriteLock)来实现读写锁定机制,允许多个线程并发读取,但只允许一个线程独占写入。
  • 条件同步:当一个线程需要在满足某个条件后才能继续执行时,可以使用条件同步技术来实现线程间的协作。Java提供了Object.wait() / notify() / notifyAll()方法, 或者 Lock.newCondition() / await() / signal() / signalAll()方法, 或者 CountDownLatch / CyclicBarrier / Semaphore / Exchanger 等工具类, 来创建和管理条件变量,并在合适的时机进行通知或等待。

下面代码采用多线程技术实现邮件发送和接收:

importjavax.mail.*;
importjavax.mail.internet.InternetAddress;
importjavax.mail.internet.MimeMessage;
importjava.util.Properties;
importjava.util.concurrent.*;
publicclassAsyncEmailSender {
privatestaticfinalStringSMTP_SERVER="smtp.163.com";// 邮箱服务器privatestaticfinalStringUSERNAME="your_email@163.com";// 邮箱账号privatestaticfinalStringPASSWORD="your_password";// 邮箱密码privatestaticfinalintNUM_THREADS=10;
privatestaticfinalExecutorServiceexecutor=Executors.newFixedThreadPool(NUM_THREADS);
privatestaticfinalStringPROXY_HOST="www.16yun.cn";// 代理服务器privatestaticfinalintPROXY_PORT=31111;// 代理yprivatestaticfinalStringPROXY_USERNAME="16YUN";// 代理用户名privatestaticfinalStringPROXY_PASSWORD="16IP";// 代理密码privatestaticfinalPropertiesPROXY_PROPERTIES=newProperties() {{
put("http.proxyHost", PROXY_HOST);
put("http.proxyPort", String.valueOf(PROXY_PORT));
put("https.proxyHost", PROXY_HOST);
put("https.proxyPort", String.valueOf(PROXY_PORT));
put("http.proxyUser", PROXY_USERNAME);
put("http.proxyPassword", PROXY_PASSWORD);
put("https.proxyUser", PROXY_USERNAME);
put("https.proxyPassword", PROXY_PASSWORD);
        }};
privatestaticintnumSent=0;
privatestaticintnumReceived=0;
publicstaticvoidmain(String[] args) throwsInterruptedException, ExecutionException {
CompletableFuture<Void>sendFuture=CompletableFuture.runAsync(() -> {
sendEmail("recipient@example.com", "Test Subject", "Test Body");
// 在此加入更多调用sendEmail方法的代码,以发送更多邮件        }, executor);
CompletableFuture<Void>receiveFuture=CompletableFuture.runAsync(() -> {
receiveEmail("inbox"); // 接收收件箱中的邮件        }, executor);
CompletableFuture<Void>allFutures=CompletableFuture.allOf(sendFuture, receiveFuture);
allFutures.get();
executor.shutdown();
System.out.println("Sent "+numSent+" emails");
System.out.println("Received "+numReceived+" emails");
    }
publicstaticvoidsendEmail(Stringrecipient, Stringsubject, Stringbody) {
// Set the properties of the SMTP serverPropertiesprops=newProperties(PROXY_PROPERTIES);
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", SMTP_SERVER);
props.put("mail.smtp.port", "25"); // 163邮箱使用的是25号端口// Create a new session with the SMTP serverSessionsession=Session.getInstance(props, newjavax.mail.Authenticator() {
protectedPasswordAuthenticationgetPasswordAuthentication() {
returnnewPasswordAuthentication(USERNAME, PASSWORD);
            }
        });
try {
// Create a new messageMessagemessage=newMimeMessage(session);
message.setFrom(newInternetAddress(USERNAME));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject(subject);
message.setText(body);
// Send the messageTransport.send(message);
synchronized (AsyncEmailSender.class) {
numSent++;
            }
        } catch (MessagingExceptione) {
        }

在这个示例中,我们使用了一个ExecutorService来创建一个线程池,构造函数的参数指定了线程池中的线程数量。使用CompletableFuture.runAsync方法将sendEmail和receiveEmail方法异步执行,在sendEmail和receiveEmail方法中,我们使用Proxy_properties将代理IP的配置添加到Properties对象中,实现了服务器IP的隐藏,在其中的sendEmail方法中,我们加入了一个synchronized块以确保numSent变量的所有操作都是同步的,避免出现竞争条件。在receiveEmail方法中,我们同样加入了一个synchronized块,以确保numReceived变量的所有操作都是同步的。在main方法中,我们调用了CompletableFuture.allOf方法等待所有异步操作完成。最后,我们打印出收发邮件的统计数据。


相关文章
|
19天前
|
Java 编译器 开发者
Java中的this关键字详解:深入理解与应用
本文深入解析了Java中`this`关键字的多种用法
88 9
|
19天前
|
Java 应用服务中间件 API
【潜意识Java】javaee中的SpringBoot在Java 开发中的应用与详细分析
本文介绍了 Spring Boot 的核心概念和使用场景,并通过一个实战项目演示了如何构建一个简单的 RESTful API。
36 5
|
19天前
|
人工智能 自然语言处理 搜索推荐
【潜意识Java】了解并详细分析Java与AIGC的结合应用和使用方式
本文介绍了如何将Java与AIGC(人工智能生成内容)技术结合,实现智能文本生成。
46 5
|
19天前
|
SQL Java 数据库连接
【潜意识Java】深入理解MyBatis,从基础到高级的深度细节应用
本文详细介绍了MyBatis,一个轻量级的Java持久化框架。内容涵盖MyBatis的基本概念、配置与环境搭建、基础操作(如创建实体类、Mapper接口及映射文件)以及CRUD操作的实现。此外,还深入探讨了高级特性,包括动态SQL和缓存机制。通过代码示例,帮助开发者更好地掌握MyBatis的使用技巧,提升数据库操作效率。总结部分强调了MyBatis的优势及其在实际开发中的应用价值。
29 1
|
1月前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
93 17
|
2月前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
29天前
|
缓存 安全 算法
Java 多线程 面试题
Java 多线程 相关基础面试题
|
2月前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
2月前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
|
2月前
|
安全 算法 Java
Java CAS原理和应用场景大揭秘:你掌握了吗?
CAS(Compare and Swap)是一种乐观锁机制,通过硬件指令实现原子操作,确保多线程环境下对共享变量的安全访问。它避免了传统互斥锁的性能开销和线程阻塞问题。CAS操作包含三个步骤:获取期望值、比较当前值与期望值是否相等、若相等则更新为新值。CAS广泛应用于高并发场景,如数据库事务、分布式锁、无锁数据结构等,但需注意ABA问题。Java中常用`java.util.concurrent.atomic`包下的类支持CAS操作。
77 2