当前位置: 首页>后端>正文

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

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

Java 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 等工具类, 来创建和管理条件变量,并在合适的时机进行通知或等待。

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

import javax.mail.*;

import javax.mail.internet.InternetAddress;

import javax.mail.internet.MimeMessage;

import java.util.Properties;

import java.util.concurrent.*;

public class AsyncEmailSender {

? ? private static final String SMTP_SERVER = "smtp.163.com";// 邮箱服务器

? ? private static final String USERNAME = "your_email@163.com";// 邮箱账号

? ? private static final String PASSWORD = "your_password";// 邮箱密码

? ? private static final int NUM_THREADS = 10;

? ? private static final ExecutorService executor = Executors.newFixedThreadPool(NUM_THREADS);

? ? private static final String PROXY_HOST = "www.16yun.cn";// 代理服务器

? ? private static final int PROXY_PORT = 31111;// 代理y

? ? private static final String PROXY_USERNAME = "16YUN";// 代理用户名

? ? private static final String PROXY_PASSWORD = "16IP";// 代理密码

? ? private static final Properties PROXY_PROPERTIES = new Properties() {{

? ? ? ? ? ? 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);

? ? ? ? }};

? ? private static int numSent = 0;

? ? private static int numReceived = 0;

? ? public static void main(String[] args) throws InterruptedException, 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");

? ? }

? ? public static void sendEmail(String recipient, String subject, String body) {

? ? ? ? // Set the properties of the SMTP server

? ? ? ? Properties props = new Properties(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 server

? ? ? ? Session session = Session.getInstance(props, new javax.mail.Authenticator() {

? ? ? ? ? ? protected PasswordAuthentication getPasswordAuthentication() {

? ? ? ? ? ? ? ? return new PasswordAuthentication(USERNAME, PASSWORD);

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? try {

? ? ? ? ? ? // Create a new message

? ? ? ? ? ? Message message = new MimeMessage(session);

? ? ? ? ? ? message.setFrom(new InternetAddress(USERNAME));

? ? ? ? ? ? message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));

? ? ? ? ? ? message.setSubject(subject);

? ? ? ? ? ? message.setText(body);

? ? ? ? ? ? // Send the message

? ? ? ? ? ? Transport.send(message);

? ? ? ? ? ? synchronized (AsyncEmailSender.class) {

? ? ? ? ? ? ? ? numSent++;

? ? ? ? ? ? }

? ? ? ? } catch (MessagingException e) {

? ? ? ? }

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


https://www.xamrdz.com/backend/3v21994168.html

相关文章: