java线程 demo_Java多线程demo
近期考慮采用Java多線程實現給用戶發(fā)短信的功能。自己做了一個簡單的demo。
demo需求如下:通過界面輸入用戶名、密碼、手機號,點擊添加,即可實時的為該用戶發(fā)一條短信。
實現過程如下:
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、新建一個線程類,實現發(fā)短信的效果。該線程類中需要定義一個線程池,線程池必須是靜態(tài)變量,作為類的成員。public?static?ConcurrentHashMap>?taskMap?=?new?ConcurrentHashMap<>();
線程類里需重寫run方法。線程實現的效果就是不斷的從線程池隊列中取出用戶信息,逐條給用戶發(fā)短信。while?(true){
ConcurrentLinkedQueue?linkedQueue?=?taskMap.get(mode);
if(null!=linkedQueue&&linkedQueue.size()>0)?{
System.out.println("linkedQue不空,取出用戶手機號,準備發(fā)短信");
TestUser?testUser?=?linkedQueue.poll();
if?(null?!=?testUser){
System.out.println("給用戶"?+?testUser.getName()?+?"發(fā)短信完畢");
}
}else?{
ConcurrentLinkedQueue?linkedQueue?=?taskMap.get(mode);
if(null!=linkedQueue&&linkedQueue.size()>0)?{
TestUser?testUser?=?linkedQueue.poll();
if(null!=testUser){
System.out.println("給用戶"+testUser.getName()+"發(fā)短信");
}
}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();
}
功能執(zhí)行過程解析:
啟動項目之后,系統(tǒng)加載service之后,會自動調用afterPropertiesSet()方法,開啟多個線程類Xproducer。此時每個線程都會執(zhí)行run方法。此時每個線程里面的線程隊列都是空的,所以每個線程都會執(zhí)行Thread.sleep()方法,處于阻塞狀態(tài)。
如果此時通過界面輸入一條用戶信息,點擊“添加”之后,系統(tǒng)會把該用戶信息添加到對應的線程中的隊列中。例如添加到了0號線程的線程隊列。那么0號線程此時再次判定隊列不為空時就會執(zhí)行相應的發(fā)送短信的功能。
本功能的重點在于service實現了接口InitializingBean的afterPropertiesSet()方法。該方法中,通過getBean方法可以得到線程類。
需要注意的是:SpringUtil類必須在service類之前被加載,否則getBean()會報NUll的錯誤。通過在啟動類中添加掃描注解來實現。如下,我們把SpringUtil類放到jar文件夾下,那么系統(tǒng)啟動的時候,就會先掃描jar下的文件,然后再掃描com下面的文件,保證SpringUtil先于Service之前被加載@SpringBootApplication(scanBasePackages?=?{"jar","com"})
總結
以上是生活随笔為你收集整理的java线程 demo_Java多线程demo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 获取java返回的数据_java调用第三
- 下一篇: python测试开发教程_文档测试