一、问题
什么是线程,什么是多线程,多线程如何使用?
二、解析
众所周知,实现多线程有两种方式,一个是继承Thread类,另一个是实现Runnable接口;
请见代码:
1.线程;
①、代码
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我在线程中执行:"+Thread.currentThread().getName());
}
});
thread.start();
}
②、运行结果:
我在线程中执行:Thread-0
Process finished with exit code 0
你可以在上面代码的run里写业务逻辑;
run(){
//业务逻辑
}
③、PS:线程的状态包括:
public enum State {
/**
* 新建状态,未准备开始执行
*/
NEW,
/**
* 正在执行
*/
RUNNABLE,
/**
* 阻塞中
*/
BLOCKED,
/**
* 等待中,等待高优先级的其他线程执行完再执行
*/
WAITING,
/**
* 定时等待,等定时一到,则开始执行
*/
TIMED_WAITING,
/**
* 终止
*/
TERMINATED;
}
2、多线程
顾名思义即多个线程,可以分担主线程的压力,加速程序执行的效率;最简单的多线程即手动写多个Thread即可,例子如下:
①、代码:
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我在线程1中执行:"+Thread.currentThread().getName());
}
});
thread1.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我在线程2中执行:"+Thread.currentThread().getName());
}
});
thread2.start();
}
②、执行结果:
我在线程1中执行:Thread-0
我在线程2中执行:Thread-1
Process finished with exit code 0
③、截图如下:
3、线程池
如果需要的线程比较多,并且需要自动启动,自我管理,不需要人为过多操行时,可以使用线程池;
参考了这个帖子里的例子,详情请移步【这里】
①、代码:
public static void main(String[] args) {
//线程执行器中设置,线程池的核心线程大小为5,最大容量为10,保持活跃时间为200ms;计时单位为毫秒;
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(5));
for (int i = 0; i < 15; i++) {
MyTask myTask = new MyTask(i);
executor.execute(myTask);
System.out.println("线程池中的线程数目:"+executor.getPoolSize()+"队列中等待执行的任务数目:"+executor.getQueue().size()
+"已执行完的任务数目:"+executor.getCompletedTaskCount());
}
//关闭线程池执行器
executor.shutdown();
}
/**
* 实体类,将自己的业务逻辑都集中在该类的run方法中;
*/
static class MyTask implements Runnable {
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
@Override
public void run() {
System.out.println("正在执行task "+taskNum);
try {
//此处写自己的业务逻辑
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task "+taskNum+"执行完毕");
}
}
②、测试结果:
正在执行task 0
线程池中的线程数目:1队列中等待执行的任务数目:0已执行完的任务数目:0
线程池中的线程数目:2队列中等待执行的任务数目:0已执行完的任务数目:0
线程池中的线程数目:3队列中等待执行的任务数目:0已执行完的任务数目:0
正在执行task 1
正在执行task 2
线程池中的线程数目:4队列中等待执行的任务数目:0已执行完的任务数目:0
线程池中的线程数目:5队列中等待执行的任务数目:0已执行完的任务数目:0
正在执行task 3
线程池中的线程数目:5队列中等待执行的任务数目:1已执行完的任务数目:0
线程池中的线程数目:5队列中等待执行的任务数目:2已执行完的任务数目:0
正在执行task 4
线程池中的线程数目:5队列中等待执行的任务数目:3已执行完的任务数目:0
线程池中的线程数目:5队列中等待执行的任务数目:4已执行完的任务数目:0
线程池中的线程数目:5队列中等待执行的任务数目:5已执行完的任务数目:0
线程池中的线程数目:6队列中等待执行的任务数目:5已执行完的任务数目:0
线程池中的线程数目:7队列中等待执行的任务数目:5已执行完的任务数目:0
正在执行task 10
正在执行task 11
线程池中的线程数目:8队列中等待执行的任务数目:5已执行完的任务数目:0
正在执行task 12
线程池中的线程数目:9队列中等待执行的任务数目:5已执行完的任务数目:0
线程池中的线程数目:10队列中等待执行的任务数目:5已执行完的任务数目:0
正在执行task 13
正在执行task 14
task 0执行完毕
task 1执行完毕
task 2执行完毕
正在执行task 7
task 11执行完毕
正在执行task 6
正在执行task 5
正在执行task 8
task 10执行完毕
task 12执行完毕
task 3执行完毕
task 4执行完毕
正在执行task 9
task 13执行完毕
task 14执行完毕
task 7执行完毕
task 6执行完毕
task 5执行完毕
task 8执行完毕
task 9执行完毕
Process finished with exit code 0
③、截图:
三、总结
如果既有的公共方法无法满足你的需求,你可以自己写一个线程池来做自己的业务,但是你要注意以下几点:
1.要有必要的日志系统,为出错时溯源;
2.最小,最大线程池大小等基本参数如何设置;
3.超时阻塞如何处理,不能一直让一个线程卡在那里;
4.如何监控线程池的状况,已使用多少,未使用多少;线程池满载情况下如何处理;
5.异常情况下如何处理;是直接报错,抛出异常,还是存表记录;
完毕;
欢迎关注我的公众号:幕桥社区