需求:多线程执行各个类的方法,执行完成后,再继续执行主线程下面的程序
1、创建父类
package com.cgx;
/**
* 动物父类
*/
public interface Animal {
void run();
void call();
}
2、创建子类
package com.cgx.impl;
import com.cgx.Animal;
public class Dog implements Animal {
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("小狗:四条腿,飞速奔跑(反应1秒)");
}
@Override
public void call() {
try {
Thread.sleep(3000);
System.out.println("汪汪汪...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.cgx.impl;
import com.cgx.Animal;
public class Cat implements Animal {
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("小猫:四条腿,灵活跳跃。(反应0.1秒)");
}
@Override
public void call() {
System.out.println("喵喵喵...");
}
}
package com.cgx.impl;
import com.cgx.Animal;
public class Bird implements Animal {
@Override
public void run() {
System.out.println("小鸟:用翅膀,飞的很快,也可以用两只脚(反应灵活,不用等待)");
}
@Override
public void call() {
System.out.println("叽叽喳喳...");
}
}
3、测试
package com;
import com.cgx.Animal;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test {
//获取cup核数
static final int nThreads = Runtime.getRuntime().availableProcessors();
public static void main(String[] args){
List<String> animals = new ArrayList<>();
animals.add("com.cgx.impl.Cat");
animals.add("com.cgx.impl.Dog");
animals.add("com.cgx.impl.Bird");
//创建线程池
//参数1:指定线程池中的线程数量,任务数小于线程数时,来新任务直接开辟新的线程去执行任务,大于线程数时,来新任务workQueue任务队列中
//参数2:线程池中最大线程数
//参数3:线程空闲多久后被销毁
//参数4:参数3的单位
//参数5:任务队列,已经添加到线程池但未被执行的任务,包含 直接提交队列、有界任务队列、无界任务队列、优先任务队列
//参数6:拒绝策略,任务太多执行不过来时,如何处理。有四种,AbortPolicy为直接抛异常。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(nThreads,nThreads,200,
TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(1000),
new ThreadPoolExecutor.AbortPolicy());
//计数器,用来控制等子线程都执行完后,再继续往下执行。
//数量为要执行的线程个数
CountDownLatch countDownLatch = new CountDownLatch(animals.size());
try {
//利用反射执行类中的方法
Method method = Animal.class.getMethod("run");
//Method method = Animal.class.getMethod("call");
for (String animal : animals) {
//启用多线程执行
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
try {
//利用反射执行指定类下的方法
method.invoke(Class.forName(animal).newInstance(),null);
//执行完,计数器减一
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
try {
//计数器阻塞,数量为0时才能继续往下执行
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("所有动物都已经表演完毕...");
}
}
4、执行结果:因为多线程,各自执行,输出顺序不一定是调用顺序;子线程都执行完成后才会执行最后一句输出语句。