守護線程與非守護線程
java中有兩種線程:守護線程、非守護線程(也叫用戶線程),用戶線程是在主線程中定義的,當主線程結束時,用戶線程不會收到影響;但是當主線程結束時,用戶線程也會跟着結束。
例如:GC線程就是守護線程,當主線程結束,GC線程也會結束。
代碼實例:
public class ThreadDemo {
public static void main(String[] args) {
//創建一個線程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
System.out.println("子線程執行: ");
}
}
});
t1.start();
for (int i = 0; i < 20; i++) {
System.out.println("主線程執行: " + i);
}
System.out.println("主線程執行完畢。。。");
}
}
這種情況下,主線程結束之後,子線程還是會繼續執行,但是如果將子線程也設置成守護線程,這樣當主線程結束時,子線程也會跟着結束
t1.start();
//將子線程設置成守護線程
t1.setDaemon(true);
多線程實例
需求:有10W用戶,需要給沒有給用戶發送一條祝福短信,爲了提高效率,使用多線程分批發送短信
創建用戶實體:
package com.dss.entity;
public class UserEntity {
private String userId;
private String userName;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public String toString() {
return "UserEntity [userId=" + userId + ", userName=" + userName + "]";
}
public UserEntity(String userId, String userName) {
super();
this.userId = userId;
this.userName = userName;
}
}
創建分頁工具類:
package com.dss.util;
import java.util.ArrayList;
import java.util.List;
/**
* 計算分頁工作類
* @author asong
*
*/
public class ListUtils {
/**
* 傳入一個集合,和每頁的記錄數,會返回一個 list<list<T>>,外面這個list是指總頁數,裏面的list是指每一頁的數據
* @param list
* @param pageSize
* @return
*/
public static <T> List<List<T>> splitList(List<T> list, int pageSize) {
int listSize = list.size();
int page = (listSize + (pageSize - 1)) / pageSize;
List<List<T>>listArray = new ArrayList<List<T>>();
for (int i = 0; i<page; i++) {
List<T> subList = new ArrayList<T>();
for (int j = 0; j<listSize; j++) {
int pageIndex = ((j + 1) + (pageSize - 1)) / pageSize;
if (pageIndex == (i + 1)) {
subList.add(list.get(j));
}
if ((j + 1) == ((j + 1) * pageSize)) {
break;
}
}
listArray.add(subList);
}
return listArray;
}
}
創建線程類:
package com.dss.thread;
import java.util.List;
import com.dss.entity.UserEntity;
public class UserThread implements Runnable{
private List<UserEntity> userList;
public UserThread(List<UserEntity> userList) {
this.userList = userList;
}
@Override
public void run() {
for (UserEntity userEntity : userList) {
System.out.println("threadName: " + Thread.currentThread().getName()
+ ", userId: " + userEntity.getUserId() + ", userName: " + userEntity.getUserName());
}
}
}
測試:
package com.dss;
import java.util.ArrayList;
import java.util.List;
import com.dss.entity.UserEntity;
import com.dss.thread.UserThread;
import com.dss.util.ListUtils;
public class Test {
public static void main(String[] args) {
//1、初始化數據
List<UserEntity> userList = new ArrayList<UserEntity>();
for(int i=0; i<10; i++) {
userList.add(new UserEntity("userId" + i, "userName" + i));
}
//2、設置每一個線程要發送短信的用戶數量
int page = 2;
//3、得到每一個線程要發送的用戶數據
List<List<UserEntity>> list = ListUtils.splitList(userList, 2);
for (int i = 0; i < list.size(); i++) {
List<UserEntity> list2 = list.get(i);
for (UserEntity userEntity : list2) {
System.out.println(userEntity);
}
}
//4、循環創建線程,發送短信
for(int i=0; i<list.size(); i++) {
//這個循環就表示要創建多少個線程
UserThread ur = new UserThread(list.get(i));
Thread t = new Thread(ur, "線程"+i); //創建線程,並且指定線程的名字
t.start();
System.out.println();
}
}
}