Thread题目测试

1. 线程池和任务执行

题目:使用 Java 的 ExecutorService 来模拟一个任务队列系统,能够执行多个任务,并且设置最大线程数。编写程序来创建并执行 10 个任务,其中每个任务会打印一个数字,模拟一个耗时的操作。

要求

  • 使用线程池来管理任务。
  • 最多只能同时执行 3 个任务,其他任务要排队。
  • 每个任务运行时模拟一些处理时间,例如使用 Thread.sleep()
import java.util.concurrent.*;

public class TaskExecutor {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 10; i++) {
            int taskId = i;
            executorService.submit(() -> {
                try {
                    Thread.sleep(1000); // 模拟耗时任务
                    System.out.println("任务 " + taskId + " 执行完毕");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executorService.shutdown();
    }
}

2. 读写锁

题目:使用 ReentrantReadWriteLock 实现一个简单的库存管理系统。模拟多线程环境下同时读取和写入库存数量的操作。

要求

  • 创建一个 Inventory 类,具有 getStock() 和 updateStock() 方法。
  • getStock() 使用读锁,updateStock() 使用写锁。
  • 启动多个线程进行库存查询和更新操作,保证库存数值的一致性。
import java.util.concurrent.locks.*;

public class Inventory {
    private int stock = 0;
    private final ReadWriteLock lock = new ReentrantReadWriteLock();

    public int getStock() {
        lock.readLock().lock();
        try {
            return stock;
        } finally {
            lock.readLock().unlock();
        }
    }

    public void updateStock(int amount) {
        lock.writeLock().lock();
        try {
            stock += amount;
        } finally {
            lock.writeLock().unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Inventory inventory = new Inventory();

        Thread writer = new Thread(() -> {
            inventory.updateStock(100);
            System.out.println("库存更新为: " + inventory.getStock());
        });

        Thread reader = new Thread(() -> {
            System.out.println("当前库存: " + inventory.getStock());
        });

        // 让 writer 线程先执行
        writer.start();
        writer.join();  // 等待 writer 线程执行完
        reader.start();
        reader.join();  // 等待 reader 线程执行完
    }
}

3. 生产者消费者模式

题目:实现一个经典的生产者消费者模式。模拟生产者和消费者通过共享缓冲区(如 BlockingQueue)进行数据交换。

要求

  • 使用 BlockingQueue 实现缓冲区。
  • 启动 2 个生产者线程和 3 个消费者线程,生产者生成数字并放入队列,消费者从队列中取出数字并处理(模拟消费)。
  • 打印每个生产者和消费者的操作。
import java.util.concurrent.*;

public class ProducerConsumer {
    private static final BlockingQueue queue = new LinkedBlockingQueue<>(10);

    static class Producer implements Runnable {
        public void run() {
            try {
                for (int i = 0; i < 10; i++) {
                    queue.put(i);
                    System.out.println("生产者生产: " + i);
                    Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    static class Consumer implements Runnable {
        public void run() {
            try {
                while (true) {
                    Integer item = queue.take();
                    System.out.println("消费者消费: " + item);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }

    public static void main(String[] args) {
        Thread producer = new Thread(new Producer());
        Thread consumer1 = new Thread(new Consumer());
        Thread consumer2 = new Thread(new Consumer());
        Thread consumer3 = new Thread(new Consumer());

        producer.start();
        consumer1.start();
        consumer2.start();
        consumer3.start();
    }
}

4. 线程安全的单例模式

题目:实现一个线程安全的单例模式(懒汉式),并确保只有在第一次使用时才创建实例,且线程安全。

要求

  • 使用双重检查锁定(Double-Checked Locking)优化性能。
  • 确保在多线程环境中不会创建多个实例。
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }

    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance();
        System.out.println(singleton);
    }
}

5. 死锁模拟与解决

题目:模拟一个死锁场景并尝试解决它。创建两个线程,分别持有两个资源,尝试获取对方的资源。通过 synchronized 实现资源的锁定。

要求

  • 使用 Thread.sleep() 模拟耗时操作,确保两个线程能进入死锁状态。
  • 使用合适的方法(如 tryLock)来避免死锁发生。
public class DeadlockSimulation {
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    static class Thread1 extends Thread {
        @Override
        public void run() {
            synchronized (lock1) {
                System.out.println("线程 1 获取到 lock1");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock2) {
                    System.out.println("线程 1 获取到 lock2");
                }
            }
        }
    }

    static class Thread2 extends Thread {
        @Override
        public void run() {
            synchronized (lock2) {
                System.out.println("线程 2 获取到 lock2");
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                synchronized (lock1) {
                    System.out.println("线程 2 获取到 lock1");
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread1();
        Thread t2 = new Thread2();

        t1.start();
        t2.start();
    }
}

6. 并发计数器

题目:设计一个线程安全的计数器,能够支持以下操作:

  • 增加一个数字。
  • 获取当前计数器值。
  • 重置计数器。
import java.util.concurrent.atomic.AtomicInteger;

public class Counter {
    private final AtomicInteger count = new AtomicInteger();

    public void increment() {
        count.incrementAndGet();
    }

    public int get() {
        return count.get();
    }

    public void reset() {
        count.set(0);
    }

    public static void main(String[] args) {
        Counter counter = new Counter();

        Thread t1 = new Thread(() -> {
            counter.increment();
            System.out.println("计数器值: " + counter.get());
        });

        Thread t2 = new Thread(() -> {
            counter.increment();
            System.out.println("计数器值: " + counter.get());
        });

        t1.start();
        t2.start();
    }
}

7. 自定义线程池

题目:实现一个简单的线程池,能够处理并发任务。模拟多个任务并发执行,并观察线程池的工作情况。

要求

  • 创建一个自定义线程池类,能够动态调整线程数。
  • 线程池中最多可以同时处理 5 个任务,任务执行完毕后线程池释放线程。
  • 模拟 20 个任务并发执行。
import java.util.concurrent.*;

public class CustomThreadPool {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 5, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10));

        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("执行任务 " + taskId);
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        executor.shutdown();
    }
}

8. 并发访问共享资源

题目:模拟多个线程对共享资源的并发访问。创建一个账户类 BankAccount,多个线程同时访问账户余额,并进行存款和取款操作。

要求

  • 使用 synchronized 或 ReentrantLock 来保证账户余额的线程安全。
  • 启动多个线程执行存款和取款操作,确保账户余额的正确性。
import java.util.concurrent.locks.*;

public class BankAccount {
    private int balance = 1000;
    private final Lock lock = new ReentrantLock();

    public void deposit(int amount) {
        lock.lock();
        try {
            balance += amount;
            System.out.println("存款后余额: " + balance);
        } finally {
            lock.unlock();
        }
    }

    public void withdraw(int amount) {
        lock.lock();
        try {
            if (balance >= amount) {
                balance -= amount;
                System.out.println("取款后余额: " + balance);
            } else {
                System.out.println("余额不足");
            }
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        BankAccount account = new BankAccount();

        Thread t1 = new Thread(() -> account.deposit(500));
        Thread t2 = new Thread(() -> account.withdraw(300));

        t1.start();
        t2.start();
    }
}

9. 并发任务调度

题目:使用 ScheduledExecutorService 来定时执行任务。创建一个定时任务,每隔 2 秒打印一次当前时间。

要求

  • 使用 ScheduledExecutorService 来调度任务。
  • 确保定时任务能够正常运行并且没有阻塞其他任务。
import java.util.concurrent.*;

public class ScheduledTask {
    public static void main(String[] args) {
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        Runnable task = () -> System.out.println("当前时间: " + System.currentTimeMillis());

        scheduler.scheduleAtFixedRate(task, 0, 2, TimeUnit.SECONDS);
    }
}

10. 线程池与异常处理

题目:在一个线程池中提交多个任务,每个任务都可能抛出异常。编写代码捕获异常并记录日志,而不让任务崩溃。

要求

  • 在任务中模拟异常(如 ArithmeticException)。
  • 捕获异常并打印日志,但任务不会影响其他任务的执行。
  • 使用 ExecutorService 来管理线程池。
import java.util.concurrent.*;

public class ExecutorWithExceptionHandling {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(3);

        for (int i = 0; i < 5; i++) {
            int taskId = i;
            executorService.submit(() -> {
                try {
                    if (taskId == 2) throw new ArithmeticException("故意抛出的异常");
                    System.out.println("任务 " + taskId + " 执行完毕");
                } catch (Exception e) {
                    System.out.println("任务 " + taskId + " 执行时发生异常: " + e.getMessage());
                }
            });
        }

        executorService.shutdown();
    }
}

你可能感兴趣的:(java,前端,算法)