守护线程与非守护线程
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();
}
}
}