多线程快速入门

1. 线程与进程的区别

应用程序:可以执行的软件,QQ、YY、快播.
进程:正在运行的应用程序,它是线程的集合。进程中一定有一个线程,这个线程就是主线程.
线程:正在独立运行的一条执行路径.
多线程:为了提高程序的运行效率。多线程并不是提高宽带速度,而是程序效率

2. 为什么要使用多线程?

为了提高程序的运行效率

3. 多线程应用场景

多线程下载、QQ、爬虫、前端开发ajax(异步上传)、分布式job(多任务调度)、分批发送短信,使用多线程体现程序的效率

4.多线程的创建方式

1.什么是同步?什么是异步?

代码从上往下执行叫同步,又叫单线程;异步(多线程),每个线程互不影响

2.创建多线程的五种方式:

a.继承Thread类
b.实现Runnable接口
c.使用匿名内部类方式
d.callable
e.线程池创建线程

代码01 继承Thread类:/thread01/src/com/mysoft/ThreadDemo01.java

package com.mysoft;

/**
 * @author lpz
 * 1.继承Thread类
 */
class Thread01 extends Thread{
	@Override
	public void run() {
		for(int i=0;i<30;i++) {
			System.out.println("子线程:"+i);
		}
	}
}

public class ThreadDemo01 {
	public static void main(String[] args) {
		// 1.创建一个线程
		Thread t1=new Thread01();
		// 2.开始执行线程 注意 开启线程不是调用run方法,而是start方法
		t1.start();
		//3.主线程
		for(int i=0;i<30;i++) {
			System.out.println("主线程:"+i);
		}
	}
}

代码02 使用Runnable接口方式创建线程:/thread01/src/com/mysoft/ThreadDemo02.java

package com.mysoft;

/**
 * 
 * @author lpz
 * 2.实现Runnable接口
 */

class Thread02 implements Runnable{

	@Override
	public void run() {
		for(int i=0;i<30;i++) {
			System.out.println("子线程:"+i);
		}
	}	
}

public class ThreadDemo02 {
	public static void main(String[] args) {
		//1.创建线程
		Thread t1=new Thread(new Thread02());
		//2.启动线程
		t1.start();
		//3.主线程
		for(int i=0;i<30;i++) {
			System.out.println("主线程:"+i);
		}
	}
}

代码03 使用匿名内部类方式创建线程:/thread01/src/com/mysoft/ThreadDemo03.java

package com.mysoft;

/**
 * 
 * @author lpz
 * 3.匿名内部类创建线程
 */

public class ThreadDemo03 {
	
	public static void main(String[] args) {
		//1.创建子线程
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				for(int i=0;i<30;i++) {
					System.out.println("子线程:"+i);
				}
			}
		}).start();
		//2.主线程
		for(int i=0;i<30;i++) {
			System.out.println("主线程:"+i);
		}
	}	
}

5. 多线程常用api

1.常用方法

	start()              获取当前线程ID
    getID()	           	 获取当前线程ID
    getName()	         获取当前线程名称
    sleep(long mill)	 休眠线程
    stop()	             停止线程

2.常用线程构造函数

    Thread()
    Thread(String name)
    Thread(Runable r)
    Thread(Runable r, String name)

代码04 多线程常用api:/thread01/src/com/mysoft/ThreadDemo04.java

package com.mysoft;

/**
 * 
 * @author lpz
 * 多线程常用api
 */
class Thread04 implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<30;i++) {
			try {
				//3.线程休眠
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			//4.获取当前线程id和name
			System.out.println("子线程id:"+Thread.currentThread().getId()+",子线程name:"+Thread.currentThread().getName());
		}
	}
}

public class ThreadDemo04 {
	public static void main(String[] args) {
		//1.获取主线程id和name
		System.out.println("主线程id:"+Thread.currentThread().getId()+",主线程name:"+Thread.currentThread().getName());
			//2.用户线程命名
			Thread t1=new Thread(new Thread04(),"子线程");
			t1.start();		
	}
}

6. 守护线程与非守护线程

守护线程:当进程不存在或主线程停止,守护线程也会被停止。
非守护线程:也叫用户线程,是指用户自定义创建的线程,主线程停止,用户线程不会停止
gc线程:是守护线程,有一个特征:和主线程一起销毁

代码05 守护线程和非守护线程:/thread01/src/com/mysoft/ThreadDemo05.java

package com.mysoft;

/**
 * 
 * @author lpz 
 * 用户线程:主线程创建的线程 
 * 守护线程:和主线程一起销毁
 */

public class ThreadDemo05 {
	public static void main(String[] args){
		// 1.匿名内部类创建线程
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				for (int i = 0; i < 30; i++) {
					try {
						// 4.子线程每循环一次休眠300ms
						Thread.sleep(300);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println("子线程:" + i);
				}

			}
		});
		// 2.启动线程
		t1.setDaemon(true);		//true表示设置为守护线程
		t1.start();
		// 3.主线程
		for (int i = 0; i < 5; i++) {
			try {
				Thread.sleep(300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("主线程:" + i);
		}
		System.out.println("主线程运行结束......");
	}
}

7. 多线程运行状态

新建状态、就绪状态、运行状态、阻塞状态、死亡状态

8. join方法作用

join作用是让其他线程变为等待, t1.join();// 让其他线程变为等待,直到当前t1线程执行完毕,才释放.在线程B中调用了线程A的Join()方法,直到线程A执行完毕后,才会继续执行线程B

代码06 join()方法的作用:/thread01/src/com/mysoft/ThreadDemo06.java

package com.mysoft;

/**
 * 
 * @author lpz
 * join()方法的作用:调用join()方法的线程执行完毕后,再执行其它线程
 */
public class ThreadDemo06 {
	public static void main(String[] args) {
		//1.匿名内部类创建线程
		Thread t1=new Thread(new Runnable() {			
			@Override
			public void run() {
				for(int i=0;i<30;i++) {
					System.out.println("子线程1:"+i);
				}				
			}
		});
		Thread t2=new Thread(new Runnable() {			
			@Override
			public void run() {
				for(int i=0;i<30;i++) {
					System.out.println("子线程2:"+i);
				}				
			}
		});
		//2.启动子线程
		t1.start();
		t2.start();
		//3.调用子线程t1.join()方法,等待子线程执行完毕后主线程才执行
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//4.子线程执行完毕后,执行主线程
		for(int i=0;i<30;i++) {
			System.out.println("主线程:"+i);
		}
	}
}

9. T1、T2、T3线程顺序执行

代码07 t1、t2、t3线程顺序执行:/thread01/src/com/mysoft/ThreadDemo07.java

package com.mysoft;

/**
 * 
 * @author lpz
 * T1、T2、T3线程顺序执行
 */

public class ThreadDemo07 {
	static ThreadDemo07 t=new ThreadDemo07();
	
	class T1 extends Thread{
		public T1(String name) {
			super(name);
		}
		@Override
		public void run() {
			for(int i=0;i<30;i++) {
				System.out.println(getName()+":"+i);
			}
		}
	}
	class T2 extends Thread{
		public T2(String name) {
			super(name);
		}
		@Override
		public void run() {
			for(int i=0;i<30;i++) {
				System.out.println(getName()+":"+i);
			}
		}
	}
	
	class T3 extends Thread{
		public T3(String name) {
			super(name);
		}
		@Override
		public void run() {
			for(int i=0;i<30;i++) {
				System.out.println(getName()+":"+i);
			}
		}
	}
	
	
	public static void main(String[] args) {
		Thread t1=t.new T1("T1");
		t1.start();
		try {
			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Thread t2=t.new T1("T2");
		t2.start();
		try {
			t2.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		Thread t3=t.new T1("T3");
		t3.start();
	}
}

10. 多线程模拟实现分批处理信息

需求:目前有10万个用户,现在做活动,给每一个用户发送一条祝福短信。为了提高数程序的效率,使用多线程模拟实现分批发送据。

创建项目thread_batch_send_message

1.创建实体类:/thread_batch_send_message/src/com/mysoft/bean/User.java

package com.mysoft.bean;

public class User {
	private String id;
	private String name;
	
	public User() {
		
	}

	public User(String id, String name) {
		this.id = id;
		this.name = name;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + "]";
	}	
}

2.创建线程类发送消息:/thread_batch_send_message/src/com/mysoft/thread/UserThread.java

package com.mysoft.thread;

import java.util.List;

import com.mysoft.bean.User;

public class UserThread extends Thread {

	private List<User> list;

	public UserThread(List<User> list) {
		this.list = list;
	}

	@Override
	public void run() {
		for (User user : list) {
			System.out.println("ThreadName:" + Thread.currentThread().getName() + ",用户编号:" + user.getId() + ",用户名字:"
					+ user.getName());
		}
	}
}

3.初始化数据:/thread_batch_send_message/src/com/mysoft/util/InitData.java

package com.mysoft.util;

import java.util.ArrayList;
import java.util.List;

import com.mysoft.bean.User;

public class InitData {
	public static List<User> initUser(int num){
		List<User> list=new ArrayList<>();
		for(int i=1;i<=num;i++) {
			User user=new User();
			user.setId("用户id"+i);
			user.setName("用户名"+i);
			list.add(user);
		}
		return list;
	}
}

4.分页工具类:/thread_batch_send_message/src/com/mysoft/util/ListUtil.java

package com.mysoft.util;

import java.util.ArrayList;
import java.util.List;

public class ListUtil {
	public static<T> List<List<T>> splitList(List<T> list,int pageSize){
		int listSize=list.size();
		int page=listSize%pageSize==0?listSize/pageSize:listSize/pageSize+1;
		List<List<T>> listArray=new ArrayList<List<T>>();
		for (int i = 1; i <=page ; i++) {
			List<T> subList=new ArrayList<T>();
			for (int j = (i-1)*pageSize; j <listSize ; j++) {
				int index=(i-1)*pageSize;
				if(index<=j && j<(i-1)*pageSize+pageSize) {
					subList.add(list.get(j));
				}
				if(j==(i-1)*pageSize+pageSize) {
					break;
				}
			}
			listArray.add(subList);
		}
		return listArray;
	}
}

5.实现发送短信:/thread_batch_send_message/src/com/mysoft/main/UserSendMessage.java

package com.mysoft.main;

import java.util.List;

import com.mysoft.bean.User;
import com.mysoft.thread.UserThread;
import com.mysoft.util.InitData;
import com.mysoft.util.ListUtil;

public class UserSendMessage {
	public static void main(String[] args) throws InterruptedException {
		//1.初始化数据
		List<User> userList = InitData.initUser(10);
		//2.定义每个线程分批发送大小
		int sendNum=2;
		//3.计算每个线程分批发送数据
		List<List<User>> list = ListUtil.splitList(userList, sendNum);
		//4.分批发送数据
		for (List<User> sendList:list) {
			Thread t=new UserThread(sendList);
			t.start();
			Thread.sleep(2000);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值