💥 该系列属于【Java基础编程500题】专栏,如您需查看Java基础的其他相关题目,请您点击左边的连接
目录
2. 实现Runnable接口,创建两个线程,分别输出奇数和偶数。
3. 使用Callable接口,计算1到100的累加和,并在主线程中输出结果。
4. 创建一个线程,实现每秒输出一次当前时间(HH:mm:ss)。
5. 创建两个线程,分别打印传入的两个字符串"Hello"和"World"。
6. 创建一个守护线程,该线程每隔100毫秒输出一次“我是守护线程”,主线程结束后,守护线程也随之结束。
7. 创建两个线程循环1000次打印,其中一个线程礼让另一个线程,观察输出结果。
8. 创建一个插队线程,让指定线程在当前线程执行完毕后立即执行。
9. 编写一个程序,创建一个守护线程和一个用户线程,观察它们的行为。
10. 编写一个程序,使用join()方法,实现线程A打印5次,然后线程B打印5次,接着线程A再次打印5次。
11. 编写一个程序,使用同步代码块确保两个线程能够交替打印数字。
12. 编写一个程序,使用同步方法确保在多个线程中对共享资源进行安全的操作,例如维护使用1000次就失效的计数器。
13. 【生产者消费者问题】编写一个程序,使用同步代码块解决生产者-消费者问题。
14. 编写一个程序,使用CountDownLatch来模拟一个简单的赛跑场景,其中5名选手需要等待裁判员发令枪响后才能开始跑步。
15. 【读者写者问题】编写一个程序,使用读写锁(ReentrantReadWriteLock)实现一个简单的缓存系统,允许多个线程读取数据,但写入数据时需要独占锁。
16. 创建一个定长线程池,包含3个线程。提交5个任务到线程池,每个任务打印当前线程的名称。
17. 创建一个定时线程池,安排一个任务在3秒后执行,任务打印当前时间。
18. 创建一个可缓存线程池,提交10个任务,每个任务打印当前线程的名称,并等待所有任务执行完毕。
19. 创建一个单线程化线程池,提交5个任务,每个任务打印当前线程的名称。
20. 创建一个自定义线程池,核心线程数为2,最大线程数为5,线程空闲时间为1分钟,工作队列容量为5。提交10个任务到线程池,每个任务打印当前线程的名称。
✨✨ 返回题目目录 ✨ ✨
1. 创建两个线程,输出1到100的数字。
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "输出:" + i);
}
}
}
public class Main {
public static void main(String[] args) {
Thread t1 = new MyThread();
Thread t2 = new MyThread();
t1.setName("线程1");
t2.setName("线程2");
t1.start();
t2.start();
}
}
2. 实现Runnable接口,创建两个线程,分别输出奇数和偶数。
class oddRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 10; i += 2) {
System.out.println("奇数线程输出:" + i);
}
}
}
class evenRunnable implements Runnable {
@Override
public void run() {
for (int i = 2; i <= 10; i += 2) {
System.out.println("偶数数线程输出:" + i);
}
}
}
public class Main {
public static void main(String[] args) {
oddRunnable oddRunnable = new oddRunnable();
evenRunnable evenRunnable = new evenRunnable();
Thread thread1 = new Thread(oddRunnable);
Thread thread2 = new Thread(evenRunnable);
thread1.start();
thread2.start();
}
}
3. 使用Callable接口,计算1到100的累加和,并在主线程中输出结果。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
class MyCallable implements Callable {
@Override
public Integer call() {
int sum = 0;
for (int i = 1; i <= 100; i++) {
sum += i;
}
return sum;
}
}
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyCallable myCallable = new MyCallable();
FutureTask futureTask = new FutureTask<>(myCallable);
Thread thread = new Thread(futureTask);
thread.start();
System.out.println(futureTask.get());
}
}
4. 创建一个线程,实现每秒输出一次当前时间(HH:mm:ss)。
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
String format = dateTimeFormatter.format(LocalTime.now());
System.out.println(format);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});
thread.start();
}
}
5. 创建两个线程,分别打印传入的两个字符串"Hello"和"World"。
class Message implements Runnable {
private final String str;
public Message(String str) {
this.str = str;
}
@Override
public void run() {
System.out.println(str);
}
}
public class Main {
public static void main(String[] args) {
Message message1 = new Message("Hello");
Message message2 = new Message("World");
Thread thread1 = new Thread(message1);
Thread thread2 = new Thread(message2);
thread1.start();
thread2.start();
}
}
6. 创建一个守护线程,该线程每隔100毫秒输出一次“我是守护线程”,主线程结束后,守护线程也随之结束。
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("我是守护线程");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
});
thread.setDaemon(true);
thread.start();
}
}
7. 创建两个线程循环1000次打印,其中一个线程礼让另一个线程,观察输出结果。
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 1000; i++) {
System.out.println("线程1正在打印" + i);
Thread.yield(); //礼让线程
}
}
});
Thread thread2 = new Thread(() -> {
for (int i = 1; i <= 1000; i++) {
System.out.println("线程2正在打印" + i);
}
});
thread1.start();
thread2.start();
}
}
8. 创建一个插队线程,让指定线程在当前线程执行完毕后立即执行。
public class Main {
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程1正在运行");
}
});
Thread t2 = new Thread(() -> {
try {
t1.join(); //t1插入
System.out.println("线程2正在执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
}
9. 编写一个程序,创建一个守护线程和一个用户线程,观察它们的行为。
public class Main {
public static void main(String[] args) {
Thread daemonThread = new Thread(() -> {
while (true) {
System.out.println("守护线程正在运行");
}
});
Thread userThread = new Thread(() -> {
for (int i = 0; i < 50; i++) {
System.out.println("用户线程正在运行");
}
});
daemonThread.setDaemon(true);
daemonThread.start();
userThread.start();
}
}
10. 编写一个程序,使用join()方法,实现线程A打印5次,然后线程B打印5次,接着线程A再次打印5次。
public class Main {
public static void main(String[] args) throws InterruptedException {
// 创建一个Runnable实例,以便可以多次创建线程来执行它
Runnable taskForThreadA = () -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程A正在运行");
}
};
Thread t1 = new Thread(taskForThreadA);
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程B正在运行");
}
});
t1.start(); // 第一次启动线程t1
t1.join(); // 等待线程t1结束
t2.start(); // 启动线程t2
t2.join(); // 等待线程t2结束
// 创建一个新的线程实例来再次执行任务,不能直接t1.start(),得创建新的
t1 = new Thread(taskForThreadA);
t1.start(); // 再次启动线程t1
t1.join(); // 等待新启动的线程t1结束
}
}
11. 编写一个程序,使用同步代码块确保两个线程能够交替打印数字。
class Print implements Runnable {
final Object lock;
static int sum = 1;
Print(Object lock) {
this.lock = lock;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + "正在打印" + (sum++));
lock.notifyAll();
try {
lock.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
public class Main {
public static void main(String[] args) {
Object lock = new Object();
Print print = new Print(lock);
Thread thread1 = new Thread(print);
Thread thread2 = new Thread(print);
thread1.start();
thread2.start();
}
}
12. 编写一个程序,使用同步方法确保在多个线程中对共享资源进行安全的操作,例如维护使用1000次就失效的计数器。
class Clock implements Runnable {
@Override
public void run() {
clock();
}
public synchronized void clock() {
for (int i = 1; i <= 1000; i++) {
System.out.println(i);
}
}
}
public class Main {
public static void main(String[] args) {
Clock clock = new Clock();
Thread thread1 = new Thread(clock);
Thread thread2 = new Thread(clock);
Thread thread3 = new Thread(clock);
thread1.start();
thread2.start();
thread3.start();
}
}
13. 【生产者消费者问题】编写一个程序,使用同步代码块解决生产者-消费者问题。
方法一:
import java.util.LinkedList;
import java.util.Queue;
class ProducerConsumer {
private final Queue<Integer> queue = new LinkedList<>();
private int capacity = 300;
public void produce() throws InterruptedException {
int value = 0;
while (true) {
synchronized (queue) {
while (queue.size() == capacity) {
queue.wait();
}
queue.add(value++);
System.out.println("生产者正在生产第: " + value + "个产品");
queue.notify();
Thread.sleep(100);
}
}
}
public void consume() throws InterruptedException {
while (true) {
synchronized (queue) {
while (queue.isEmpty()) {
queue.wait();
}
int value = queue.poll();
System.out.println("消费者正在消费第: " + value + "个产品");
queue.notify();
Thread.sleep(100);
}
}
}
}
public class Main {
public static void main(String[] args) {
ProducerConsumer pc = new ProducerConsumer();
Thread t1 = new Thread(() -> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t1.start();
t2.start();
}
}
方法二:
import java.util.LinkedList;
import java.util.Queue;
class Box {
final int capacity;
Queue<Integer> queue = new LinkedList<>();
Box(int capacity) {
this.capacity = capacity;
}
public Integer poll() {
return queue.poll();
}
public void push(Integer i) {
queue.add(i);
}
public int Capacity() {
return queue.size();
}
public int MaxCapacity() {
return capacity;
}
}
class Producer implements Runnable {
private Box box;
public Producer(Box box) {
this.box = box;
}
@Override
public void run() {
for (int i = 0; i <= 1000; i++) {
synchronized (box) {
while (box.Capacity() == box.MaxCapacity()) {
try {
box.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
box.push(i);
System.out.println("生产者生产了第" + i + "个产品");
box.notifyAll();
}
}
}
}
class Consumer implements Runnable {
private Box box;
public Consumer(Box box) {
this.box = box;
}
@Override
public void run() {
for (int i = 0; i <= 1000; i++) {
synchronized (box) {
while (box.Capacity() == 0) {
try {
box.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
Integer poll = box.poll();
System.out.println("消费者消费了第" + poll + "个产品");
box.notifyAll();
}
}
}
}
public class Main {
public static void main(String[] args) {
Box box = new Box(300);
Producer producer = new Producer(box);
Consumer consumer = new Consumer(box);
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(consumer);
thread1.start();
thread2.start();
}
}
14. 编写一个程序,使用CountDownLatch来模拟一个简单的赛跑场景,其中5名选手需要等待裁判员发令枪响后才能开始跑步。
import java.util.concurrent.CountDownLatch;
public class ThreadTest7 {
public static void main(String[] args) {
CountDownLatch startSignal = new CountDownLatch(1);
for (int i = 1; i <= 5; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + "正在等待发令枪响...");
startSignal.await();
System.out.println(Thread.currentThread().getName() + "开始跑步!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "选手" + i).start();
}
System.out.println("裁判员准备发令枪...");
startSignal.countDown(); // 发令枪响
}
}
15. 【读者写者问题】编写一个程序,使用读写锁(ReentrantReadWriteLock)实现一个简单的缓存系统,允许多个线程读取数据,但写入数据时需要独占锁。
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Main {
public static void main(String[] args) throws InterruptedException {
Cache cache = new Cache();
for (int i = 0; i < 15; i++) {
int finalI = i;
Thread thread = new Thread(() -> cache.write(finalI, "数据" + finalI));
thread.join();
thread.start();
}
Thread.sleep(1000);
for (int i = 0; i < 15; i++) {
int finalI = i;
new Thread(() -> System.out.println("读取数据:" + cache.read(finalI))).start();
}
}
}
class Cache {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Map<Integer, String> map = new HashMap<>();
public void write(Integer key, String value) {
readWriteLock.writeLock().lock();
try {
System.out.println("写入数据:" + key + " - " + value);
map.put(key, value);
} finally {
readWriteLock.writeLock().unlock();
}
}
public String read(Integer key) {
readWriteLock.readLock().lock();
try {
return map.get(key);
} finally {
readWriteLock.readLock().unlock();
}
}
}
16. 创建一个定长线程池,包含3个线程。提交5个任务到线程池,每个任务打印当前线程的名称。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyTask extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在执行");
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 300; i++) {
executorService.execute(new MyTask());
}
executorService.shutdown();
}
}
17. 创建一个定时线程池,安排一个任务在3秒后执行,任务打印当前时间。
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class MyTask extends Thread {
@Override
public void run() {
System.out.println(LocalDateTime.now());
}
}
public class Main {
public static void main(String[] args) {
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(5);
scheduledExecutorService.schedule(new MyTask(), 3, TimeUnit.SECONDS);
scheduledExecutorService.shutdown();
}
}
18. 创建一个可缓存线程池,提交10个任务,每个任务打印当前线程的名称,并等待所有任务执行完毕。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class CacheTask implements Runnable {
public void run() {
System.out.println("执行缓存线程池任务:" + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
executor.execute(new CacheTask());
}
executor.shutdown();
}
}
19. 创建一个单线程化线程池,提交5个任务,每个任务打印当前线程的名称。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class SingleTask implements Runnable {
public void run() {
System.out.println("执行单线程任务:" + Thread.currentThread().getName());
}
}
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
executor.execute(new SingleTask());
}
executor.shutdown();
}
}
20. 创建一个自定义线程池,核心线程数为2,最大线程数为5,线程空闲时间为1分钟,工作队列容量为5。提交10个任务到线程池,每个任务打印当前线程的名称。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
class Task implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "正在执行");
}
}
public class Main {
public static void main(String[] args) {
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
2, //核心线程数量
5, //最大线程数量
1, //线程空闲时间
TimeUnit.MINUTES, // 时间单位
new ArrayBlockingQueue<>(5) //队列
);
for (int i = 1; i <= 10; i++) {
threadPoolExecutor.execute(new Task());
}
threadPoolExecutor.shutdown();
}
}