|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 moc 于 2019-1-13 22:53 编辑
1、线程组
把多个线程组合到一起,对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
- // 线程子类
- public class MyRunnable implements Runnable {
- @Override
- public void run() {
- for (int x = 0; x < 100; x++) {
- System.out.println(Thread.currentThread().getName() + ":" + x);
- }
- }
- }
- // 测试类
- public class ThreadGroupDemo {
- public static void main(String[] args) {
- MyRunnable my = new MyRunnable();
- Thread t1 = new Thread(my, "小明");
- Thread t2 = new Thread(my, "小华");
- // public final ThreadGroup getThreadGroup() 查看线程属于哪个组,获得线程组
- ThreadGroup tg1 = t1.getThreadGroup();
- ThreadGroup tg2 = t2.getThreadGroup();
-
- // public final String getName() 查看线程组的名称
- String name1 = tg1.getName();
- String name2 = tg2.getName();
- System.out.println(name1);
- System.out.println(name2);
- System.out.println(Thread.currentThread().getThreadGroup().getName());
- // 通过结果知道:线程默认情况下属于main线程组
- // 通过下面的测试,你应该能够看到,默任情况下,所有的线程都属于同一个组
-
- // ThreadGroup(String name) 创建新的分组
- ThreadGroup tg = new ThreadGroup("这是一个新的组");
-
- // Thread(ThreadGroup group, Runnable target, String name)
- Thread t3 = new Thread(tg, my, "小王");
- Thread t4 = new Thread(tg, my, "小刘");
-
- System.out.println(t1.getThreadGroup().getName());
- System.out.println(t2.getThreadGroup().getName());
-
- //通过组名称设置后台线程,表示该组的线程都是后台线程
- tg.setDaemon(true);
- }
- }
复制代码 2、线程池简介
1. 线程池的优点
① 线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用。
③ 可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃。
2. 线程池的实现原理
提交一个任务到线程池中,线程池的处理流程如下:
① 当提交一个任务时,线程池创建一个新线程并执行任务,直到当前线程数等于核心线程数(corePoolSize),等于后再有任务进入②;
② 线程池判断工作队列是否已满,如果工作队列没有满,则将新提交的任务存储在这个工作队列里。如果工作队列满了,则进入③;
③ 判断线程池里的线程是否都处于工作状态,如果没有,则创建一个新的工作线程来执行任务。如果已经满了,则交给饱和策略来处理这个任务。
四种线程池:
public static ExecutorService newCachedThreadPool() --------------------------------------> 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
public static ExecutorService newFixedThreadPool(int nThreads) -------------------------> 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) ----> 创建一个定长线程池,支持定时及周期性任务执行。
public static ExecutorService newSingleThreadExecutor() -----------------------------------> 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
3、线程实现方式3: 实现Callable接口
步骤:
① 创建一个线程池对象,控制要创建几个线程对象,线程池可以执行Runnable对象或者Callable对象代表的线程;
② 实现Callable 接口的类;
③ 调用如下方法即可 submit方法;
④ 结束线程池。
线程求和案例:
- // Callable 接口实现类;
- public class MyCallable implements Callable<Integer> {
- private int number;
- public MyCallable(int number) {
- this.number = number;
- }
- @Override
- public Integer call() throws Exception {
- int sum = 0;
- for (int x = 1; x <= number; x++) {
- sum += x;
- }
- return sum;
- }
- }
- // 测试类
- ublic class CallableDemo {
- public static void main(String[] args) throws InterruptedException, ExecutionException {
- // 创建线程池对象
- ExecutorService pool = Executors.newFixedThreadPool(2);
- // 可以执行Runnable对象或者Callable对象代表的线程
- Future<Integer> f1 = pool.submit(new MyCallable(100));
- Future<Integer> f2 = pool.submit(new MyCallable(200));
- // V get()
- Integer i1 = f1.get();
- Integer i2 = f2.get();
- System.out.println(i1);
- System.out.println(i2);
- // 结束
- pool.shutdown();
- }
- }
复制代码 4、匿名内部类实现多线程
这种方式用于只执行一次的复杂任务。
本质:是该类或者接口的子类对象。
- public class ThreadDemo {
- public static void main(String[] args) {
- // 继承Thread类来实现多线程
- new Thread() {
- public void run() {
- for (int x = 0; x < 10; x++) {
- System.out.println(Thread.currentThread().getName() + ":" + x);
- }
- }
- }.start();
- // 实现Runnable接口来实现多线程
- new Thread(new Runnable() {
- @Override
- public void run() {
- for (int x = 0; x < 10; x++) {
- System.out.println(Thread.currentThread().getName() + ":" + x);
- }
- }
- }) {
- }.start();
- // 都写啦,只会执行继承来的,即world那一个
- new Thread(new Runnable() {
- @Override
- public void run() {
- for (int x = 0; x < 10; x++) {
- System.out.println("hello" + ":" + x);
- }
- }
- } {
- public void run() {
- for (int x = 0; x < 100; x++) {
- System.out.println("world" + ":" + x);
- }
- }
- }.start();
- }
- }
复制代码
5、定时器
让我们在指定的时间做某件事情或固定时间间隔重复性做某件事情。
包: java.util.Timer、java.util.TimerTask
方法:
Timer: 定时
Timer([String name] [,boolean isDaemon]) ------------------------------> 构造函数,创建一个计时器,【指定相关的线程的名称】,【指定作为守护线程运行】
public void schedule(TimerTask task, long delay) ------------------------> 安排在指定延迟后执行指定的任务。
public void schedule(TimerTask task,long delay,long period) ----------> 安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。
public void cancel() -----------------------------------------------------------> 终止此计时器,丢弃所有当前已安排的任务。
public void schedule(TimerTask task, Date firstTime[,long period]) --->安排指定的任务在指定的时间【开始进行重复的固定】延迟执行。
TimerTask: 任务
public abstract void run() --------> 此计时器任务要执行的操作。
public boolean cancel() ----------> 取消此计时器任务。
- // 定时器任务
- class MyTask extends TimerTask {
- @Override
- public void run() {
- System.out.println("beng,爆炸了");
- }
- }
- // 测试类
- public class TimerDemo2 {
- public static void main(String[] args) {
- // 创建定时器对象
- Timer t = new Timer();
- // 3秒后执行爆炸任务第一次,每隔2秒再继续炸
- t.schedule(new MyTask2(), 3000, 2000);
- }
- }
复制代码 |
|