java多线程的使用

1、绪论

  本博客内容较基础,适用于java基础比较薄弱的人群。通过这篇文章可以让你学会简单的创建线程的方法。

  在java程序编程过程中,你可能会遇到这种情况:某个程序运行时间很长,假设超过5s吧!这时候让界面卡在某个界面5s+显然是不行的,用户交互不友好。

  这个时候你就可能要用到多线程了。新建一个线程,把运行时间长的程序块放进去,其他代码照常运行。这样界面就不会卡在某个地方,只不过刚刚这个程序块需要的数据可能暂时没有获取到。

  只是语言描述有点难以理解,下面放代码,通过代码来继续解释。

2、代码

/**
* 获得车流量前三的卡扣,及卡扣车流量
* @return
*/
@RequestMapping(value="/getSumTop3",method=RequestMethod.POST,produces="application/json;charset=utf-8")
@ResponseBody
public R getSumTop3(String startDate,String endDate){
	//2018-11-29T23:59  ==》 2018-11-29 23:59
	startDate = startDate.replace("T"," ");
	endDate = endDate.replace('T',' ');

	//把时间封装一下
	ArrayList<String> startTime = new ArrayList<String>();
	startTime.add(startDate);
	ArrayList<String> endTime = new ArrayList<String>();
	endTime.add(endDate);

	//参数封装到Map里
	Map<String, Object> map = new HashMap();
	map.put("startDate",startTime);
	map.put("endDate",endTime);
	JSONObject jsonObject = new JSONObject(map);

	String jsonString = jsonObject.toJSONString();

	//把参数封装到Task对象中
	Task task = new Task();
	task.setTaskParam(jsonString);
	task.setTaskName("车流量top3");

	//把这个task插入到数据库,并且返回taskId
	final int taskId = taskService.insert(task);

	//根据taskId从数据库读出这三条数据
	final String cmd = "spark-submit --master spark://node01:7077 --class com.hpe.traffic.monitor.TrafficSumTop3 /opt/tmp/TrafficSumTop3.jar " + taskId;

	new Thread(new Runnable() {
		@Override
		public void run() {
			try {
				taskService.executor(taskId, cmd);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}).start();

	//上面的操作已经把车流量前三的数据插到数据库了
	//接下来,从数据库把值拿出来展示


     return R.ok().put("taskId",taskId);
 }

  上面是我写的一个Controller控制层中的一个方法。

  重点是下面这一段:

new Thread(new Runnable() {
		@Override
		public void run() {
			try {
				taskService.executor(taskId, cmd);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}).start();

  在这段代码中,由于taskService.executor(taskId, cmd);查询时间比较长(在服务器上查询的几百万条数据,大约40s),于是我直接在这个地方另起一个线程,在线程中执行这段代码,此时其余代码在原线程中正常运行。

  此时前台显示的列表肯定是没有数据的,我此时拿到了这个任务taskId的值,然后js中就根据这个taskId每个3s查询一次数据库。这样就实现了异步处理的问题。

  如果你实在不懂的话,直接复制上面那一小段代码,稍微改一下就能用!

3、总结

  由于项目经验有限,可能处理的方式不太好。有大佬有好的建议可以提出来。共勉!!!

1. 建立三个线程,并且同时运行它们。当运行时输出线程的名称。 实验步骤: (1)、创建类sy6_1 (2)、创建三个线程,调用start()方法启动这三个线程 (3)、保存文件,调试并编译运行程序。 参考程序运行效果: 2. 实现3个类:Storage、Counter和Printer。 Storage类应存储整数。 Counter应创建线程线程从0开始计数(0,1,2,3…)并将每个值存储到Storage类中。 Printer类应创建一个线程线程读取Storage类中的值并打印值。编写程序创建Storage类的实例,并创建一个Counter对象和Printer对象操作此实例。 实验步骤: (1)、创建三个类Counter, Printer,Storage (2)、创建TestCounter类,在该类中定义main函数,在main函数中定义Storage对象、Counter对象和 Printer对象,创建Counter线程和Printer线程并启动 (3)、保存文件,调试并编译运行程序。 参考程序运行效果: 3. 修改实验1第2题的程序,添加适当代码,以确保每个数字都恰好只被打印一次。 实验步骤: (1)、创建三个类Counter, Printer,Storage (2)、 创建TestCounter类,在该类中定义main函数,在main函数中定义Storage对象、Counter1对象和 Printer对象,创建Counter线程和Printer线程并启动 (3)、在定义Storage类中的setValue(int i) 和getValue ()方法时使用synchronized关键字,将其定义为同步方法 (4)、保存文件,调试并编译运行程序。 参考程序运行效果:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值