创建两个线程,一个线程输出奇数,一个线程输出偶数,实现按照1~10的顺序输出
代码实现1
java
public class OddEvenNumber {
// volatile关键字修饰的变量保证了可见性,即对该变量的写操作对其他线程可见。
private volatile int num = 1;
public static void main(String[] args) {
OddEvenNumber number = new OddEvenNumber();
new Thread(() -> number.technology()).start();
new Thread(() -> number.even()).start();
}
public synchronized void technology() {
while (num < 11) {
if (num % 2 != 0) {
System.out.println(num);
num++;
} else {
notify();
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public synchronized void even() {
while (num < 11) {
if (num % 2 == 0) {
System.out.println(num);
num++;
} else {
notify();
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
代码实现2
java
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPoolExecutorExample {
public static void main(String[] args) {
// 核心线程数为2,最大线程数为2,线程空闲时间为10秒,使用无边界队列
// 使用默认的线程工厂和饱和策略
ThreadPoolExecutor executor = new ThreadPoolExecutor(
2, 2, 1, TimeUnit.SECONDS, new LinkedBlockingDeque<>() //, new ThreadPoolExecutor.CallerRunsPolicy()
);
// 提交任务给线程池执行
// submit()方法也接受一个 Runnable 对象作为参数,但它返回一个 Future 对象,用于异步获取任务执行结果或者取消任务执行。
// 方法没有返回值,如果任务执行过程中出现异常或错误,它不会抛出该异常或错误,只会简单地打印出异常栈信息。
AtomicInteger num = new AtomicInteger(1); // 初始值为1,线程安全的,原子类
executor.submit(() -> {
while (num.get() <= 10) {
if (num.get() % 2 == 0) {
System.out.println(num.get());
num.incrementAndGet(); // 等同于 num++
}
}
});
// execute()方法接受一个 Runnable 对象作为参数,将其提交到线程池中执行。
// 方法没有返回值,如果任务执行过程中出现异常或错误,它不会抛出该异常或错误,只会简单地打印出异常栈信息。
executor.execute(() -> {
while (num.get() < 10) {
if (num.get() % 2 != 0) {
System.out.println(num.get());
num.incrementAndGet(); // 等同于 num++
}
}
});
//关闭线程池
executor.shutdown();
}
}