多线程使用实例

需求:

/**
* 注册登录发送邮件案例
* 1 存用户信息到"用户"表 假如需要3秒
* 2 存用户上传附件到"附件"表 假如需要5秒
* 3 发送邮件通知用户激活 假如需要10秒
* 4 注册成功提示 假如需要1秒
*
* 如果用户填写完信息点击"注册"后总共需要19秒才可以看见成功信息, 期间用户很可能会认为没有注册成功而重复点击注册按钮
* 如何缩短注册到看到成功回调信息的时间? 答案: 多线程, 由于使用sleep模拟真实情景, 但是sleep会阻塞线程所以还是要配上interrupt方法使用真实情景不需要的
* 每次创建都需要不断的创建新的线程, 浪费内存开销, 怎么解决? 答案: 使用线程池(类似于数据库连接池的原理)
*/

正常处理流程从上到下一次执行

public static void main(String[] args) throws InterruptedException {
        
        //PS: 使用 Thread.sleep(long millis);演示等待时间效果
        
        Thread.sleep(1000 * 3);
        System.out.println("1 存用户信息到"用户"表 成功");
        
        Thread.sleep(1000 * 5);
        System.out.println("2 存用户上传附件到"附件"表 成功");
        
        Thread.sleep(1000 * 10);
        System.out.println("3 发送邮件通知用户激活 成功");
        
        Thread.sleep(1000);
        System.out.println("4 注册成功提示");
        
        System.out.println("用户已经等的不耐烦了......");
        
    }

输出如下(自己运行看效果): 基本上是一个一个往控制台上蹦

1 存用户信息到"用户"表 成功
2 存用户上传附件到"附件"表 成功
3 发送邮件通知用户激活 成功
4 注册成功提示
用户已经等的不耐烦了......

使用多线程解使用sleep方法模拟时长由于调用sleep函数后会阻塞当前线程, 可以使用interrupt(); 方法使当前执行的线程退出阻塞状态

	public static void main(String[] args) {
		// 1
		Thread userInfoThread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("保存用户信息到用户表开始...");
				try {
					Thread.sleep(1000 * 3);
					System.out.println("1 存用户信息到"用户"表 成功");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("保存用户信息到用户表结束...");
			}
		});
		
		userInfoThread.start();
		System.out.println(userInfoThread.getName());
		System.out.println("用户基本信息线程关闭");
		Thread.interrupted();
		
		// 2
		Thread attachmentThread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("保存附件信息到附件表开始...");
				try {
					Thread.sleep(1000 * 5);
					System.out.println("2 存用户上传附件到"附件"表 成功");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("保存附件信息到附件表结束...");
			}
		});
		
		attachmentThread.start();
		System.out.println(attachmentThread.getName());
		System.out.println("附件信息线程关闭");
		Thread.interrupted();
		
		Thread mailThread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("处理发送邮件开始...");
				try {
					Thread.sleep(1000*10);
					System.out.println("3 发送邮件通知用户激活 成功");
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("处理发送邮件结束...");
			}
		});
		
		mailThread.start();
		System.out.println(mailThread.getName());
		System.out.println("邮件线程关闭");
		Thread.interrupted();
		
		Thread callBackThread = new Thread(new Runnable() {
			@Override
			public void run() {
				System.out.println("4 注册成功提示");
			}
		});
		
		callBackThread.start();
		System.out.println(callBackThread.getName());
		System.out.println("注册回调信息线程关闭");
		Thread.currentThread().interrupt();
		
	}

输出如下:

Thread-0
保存用户信息到用户表开始...
用户基本信息线程关闭
Thread-1
附件信息线程关闭
保存附件信息到附件表开始...
Thread-2
邮件线程关闭
处理发送邮件开始...
Thread-3
注册回调信息线程关闭
4 注册成功提示
1 存用户信息到"用户"表 成功
保存用户信息到用户表结束...
2 存用户上传附件到"附件"表 成功
保存附件信息到附件表结束...
3 发送邮件通知用户激活 成功
处理发送邮件结束...

注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。

原文地址:https://www.cnblogs.com/YingYue/p/7482652.html