java线程 demo_Java多线程demo

近期考虑采用Java多线程实现给用户发短信的功能。自己做了一个简单的demo。

demo需求如下:通过界面输入用户名、密码、手机号,点击添加,即可实时的为该用户发一条短信。

b5d50f141f9b5a412fc137eb3ed31a5b.png

实现过程如下:

2、点击“添加”,通过ajax将参数传给后台。$.ajax({

type: "post",

url:"/test/addTestUserToQue",

contentType: "application/json;charset=UTF-8",//指定消息请求类型

dataType: "json",

data:JSON.stringify({

"name":$("#name").val(),

"password":$("#password").val(),

"phone":$("#phone").val()

}),

success:function (result){

if (result.msg=="OK"){

console.log("用户添加队列成功!")

}

},

error:function (result){

console.log("data-msg:"+result.msg);

}

注意:(1)contentType:"application/json;charset=UTF-8"这个必须加上,当时因为没有加,一直请求不到后台。

(2)data属性的值是通过JSON.stringify()来转换的。

3、controller层-后台接收方法如下:public JSONResult addTestUserToQue(@RequestBody TestUser testUser){

testUserService.addTestUserToQue(testUser);

return JSONResult.ok(testUser);

}

4、service层是具体的逻辑。会把该条用户信息加到对应的线程队列中。public void addTestUserToQue(TestUser testUser) {

System.out.println("添加用户进队列service--begin--");

System.out.println("手机号最后一位:"+testUser.getPhone().substring(10));

ConcurrentLinkedQueue linkedQueue = Xproducer.taskMap.get(testUser.getPhone().substring(10));

if (linkedQueue==null){

System.out.println("linkedQueue == null,需新建");

linkedQueue = new ConcurrentLinkedQueue();

}

linkedQueue.add(testUser);

Xproducer.taskMap.put(testUser.getPhone().substring(10),linkedQueue);

System.out.println("添加用户进队列service--end--");

}

5、新建一个线程类,实现发短信的效果。该线程类中需要定义一个线程池,线程池必须是静态变量,作为类的成员。public static ConcurrentHashMap> taskMap = new ConcurrentHashMap<>();

线程类里需重写run方法。线程实现的效果就是不断的从线程池队列中取出用户信息,逐条给用户发短信。while (true){

ConcurrentLinkedQueue linkedQueue = taskMap.get(mode);

if(null!=linkedQueue&&linkedQueue.size()>0) {

System.out.println("linkedQue不空,取出用户手机号,准备发短信");

TestUser testUser = linkedQueue.poll();

if (null != testUser){

System.out.println("给用户" + testUser.getName() + "发短信完毕");

}

}else {

ConcurrentLinkedQueue linkedQueue = taskMap.get(mode);

if(null!=linkedQueue&&linkedQueue.size()>0) {

TestUser testUser = linkedQueue.poll();

if(null!=testUser){

System.out.println("给用户"+testUser.getName()+"发短信");

}

}else{

Thread.sleep(1000);

}

}

}

6、service层实现接口InitializingBean。通过重写afterPropertiesSet()方法,实现程序预加载。预加载时开启多个线程类,相当于做一个初始化。for (int i=0; i

Xproducer xproducer = SpringUtil.getBean(Xproducer.class);

xproducer.setMode(i+"");

xproducer.setThreadName("thread"+i);

Thread thread = new Thread(xproducer);

thread.start();

}

功能执行过程解析:

启动项目之后,系统加载service之后,会自动调用afterPropertiesSet()方法,开启多个线程类Xproducer。此时每个线程都会执行run方法。此时每个线程里面的线程队列都是空的,所以每个线程都会执行Thread.sleep()方法,处于阻塞状态。

如果此时通过界面输入一条用户信息,点击“添加”之后,系统会把该用户信息添加到对应的线程中的队列中。例如添加到了0号线程的线程队列。那么0号线程此时再次判定队列不为空时就会执行相应的发送短信的功能。

本功能的重点在于service实现了接口InitializingBean的afterPropertiesSet()方法。该方法中,通过getBean方法可以得到线程类。

需要注意的是:SpringUtil类必须在service类之前被加载,否则getBean()会报NUll的错误。通过在启动类中添加扫描注解来实现。如下,我们把SpringUtil类放到jar文件夹下,那么系统启动的时候,就会先扫描jar下的文件,然后再扫描com下面的文件,保证SpringUtil先于Service之前被加载@SpringBootApplication(scanBasePackages = {"jar","com"})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值