java多線程學習(一)—— 入門

守護線程與非守護線程

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();
		}
		
	}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章