线程
线程创建三种方式
继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程MyThread输出:" + i);
}
}
}
public class ThreadTest1 {
public static void main(String[] args) {
Thread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程输出:" + i);
}
}
}
实现Runnable接口
定义子类写法
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程MyRunnable执行:" + i);
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
MyRunnable myRunnable = new MyRunnable();
Thread thread = new Thread(myRunnable);
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程执行:" + i);
}
}
}
匿名内部类写法
public class ThreadTest2_2 {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println("子线程1执行了:" + i);
}
}
}).start();
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("子线程2执行了:" + i);
}
});
thread.start();
for (int i = 0; i < 5; i++) {
System.out.println("主线程执行了:" + i);
}
}
}
实现Callable接口
public class MyCallable implements Callable<Integer> {
private int start;
private int end;
public MyCallable(int start, int end) {
this.start = start;
this.end = end;
}
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = start; i <= end; i++) {
sum += i;
}
return sum;
}
}
public class ThreadTest3 {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 3、创建一个Callable的对象
Callable<Integer> c1 = new MyCallable(1, 10)
// 4、把Callable的对象封装成一个FutureTask对象(任务对象)
// 未来任务对象的作用?
// 1、是一个任务对象,实现了Runnable对象.
// 2、可以在线程执行完毕之后,用未来任务对象调用get方法获取线程执行完毕后的结果。
FutureTask<Integer> task1 = new FutureTask<>(c1)
// 5、把任务对象交给一个Thread对象
new Thread(task1).start()
Callable<Integer> c2 = new MyCallable(11, 20)
FutureTask<Integer> task2 = new FutureTask<>(c2)
new Thread(task2).start()
// 6、获取线程执行完毕后返回的结果。
// 注意:如果执行到这儿,假如上面的线程还没有执行完毕
// 这里的代码会暂停,等待上面线程执行完毕后才会获取结果。
Integer sum1 = task1.get()
Integer sum2 = task2.get()
int sum3 = 0
for (int i = 21
sum3 += i
}
System.out.println("通过三个线程合力完成了这个" +
"复杂计算:1~30的和" + (sum1 + sum2 + sum3))
}
}
线程池
线程池创建
public class ThreadPoolTest2 {
public static void main(String[] args) {
System.out.println(Runtime.getRuntime().availableProcessors());
ExecutorService executor = new ThreadPoolExecutor(3, // 核心线程数
5, // 最大线程数
8, // 额外线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(4),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
MyRunnable1 runnable1 = new MyRunnable1();
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
executor.execute(runnable1);
}
}
线程池工具类
public class ThreadPoolUtil {
private static final ExecutorService LOGIN_THREAD_POOL = new ThreadPoolExecutor(3,
5,
8,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(20),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
public static void executeLoginJob(Runnable runnable) {
LOGIN_THREAD_POOL.execute(runnable);
}
}
public class ThreadDemo2 {
public static final Logger LOGGER = LoggerFactory.getLogger(ThreadDemo2.class);
public static void main(String[] args) throws InterruptedException {
ThreadPoolUtil.executeLoginJob(() -> login());
ThreadPoolUtil.executeLoginJob(() -> login());
ThreadPoolUtil.executeLoginJob(() -> login());
}
public static void login() {
long start = System.currentTimeMillis();
storeLoginMessage();
getAd();
checkAddress();
long end = System.currentTimeMillis();
LOGGER.info("共耗时:{}毫秒", (end - start));
}
private static void storeLoginMessage() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("记录登录信息-->用时500毫秒");
}
private static void getAd() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("广告推送-->用时1000毫秒");
}
private static void checkAddress() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("检测登录地址-->用时1000毫秒");
}
}