多线程面试常问

一、创建线程的几种方式

1、继承Thread类并重写run()方法。

public class MyThread extends Thread {
	@Override
	public void run() {

		System.out.println("通过集成 Thread 类实现线程");
}
}
// 如何使用
new MyThread().start()

2、实现Runnable接口并重写run()方法。将Runnable实例作为Thread类的构造函数参数传递并启动线程。

public class MyRunnable implements Runnable {
@Override
public void run() {

System.out.println("通过实现 Runnable 方式实现线程");
}
}
// 使用
// 1、创建MyRunnable实例
MyRunnable runnable = new MyRunnable();
//2.创建Thread对象
//3.将MyRunnable放入Thread实例中
Thread thread = new Thread(runnable);
//4.通过线程对象操作线程(运行、停止)
thread.start();


3、实现Callable接口并重写call()方法。使用ExecutorService的submit()方法提交Callable任务,并通过Future对象获取返回值。

public class MyCallable implements Callable<Integer> {
	@Override
	public Integer call() throws Exception {
	
			return new Random().nextInt();

}
// 使用方法
// 1、创建线程池
ExecutorService service = Executors.newFixedThreadPool(10);
// 2、提交任务,并用 Future提交返回结果
Future<Integer> future = service.submit(new MyCallable());
}

4.使用线程池。线程池可以重复使用线程,提高性能和可靠性。Java提供了Executor框架来管理线程池。常见的线程池实现类包括ThreadPoolExecutor和ScheduledThreadPoolExecutor

public class ThreadPool {
   public static void main(String[] args) {

		//1. 提供指定线程数量的线程池
		
		ExecutorService service = Executors.newFixedThreadPool(1);
		
		//输出class java.util.concurrent.ThreadPoolExecutor
		
		System.out.println(service.getClass());

		ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
		
		//自定义线程池的属性
		
		//        service1.setCorePoolSize(15);
		//        service1.setKeepAliveTime();
		//2. 执行指定的线程的操作。需要提供实现Runnable接口或Callable接口实现类的对象
		service.execute(new NumberThread());//适用于Runnable
		service.execute(new NumberThread1());//适用于Runnable
		//        service.submit(Callable callable);//适合使用于Callable
		//3. 关闭连接池
		service.shutdown();
		}
		}

 

二、线程的几种状态

 

 

二、如何保证线程执行顺序

使用join,可以等待线程执行完成

三、notify和notifyAll的区别

notify只是随机唤醒一个线程

notifyAll是唤醒所有的线程

四、java中wait和sleep方法的不同

五、锁升级过程

 六、Volatile关键字的理解

七、synchronized和Lock锁区别

八、ReentranLock锁

线程池 

1、线程池有哪些核心参数

最大线程数:=核心线程数+救急线程数

核心线程数

阻塞队列:WorkQueue,当没有空闲核心线程数时,新来的任务就会加入到此队列,队列满就会创建救急线程执行任务

救急线程得存活时间:keepAliveTime 生存时间内没有新任务就会资源释放

时间单位:unit救急线程的存活时间单位

线程工厂:threadFactory-可以定制线程对象的创建,例如设置线程名称,是否守护线程等

拒绝策略:当所有的线程都在工作,阻塞队列也满了,就会触发拒绝策略

2、常见的阻塞队列

3、如何确定核心线程数 

4、线程池的种类

5、你是怎么使用线程池呢?

 所以一般不推荐使用Excetors去直接创建线程池,一般通过ThreadPoolExcetors去自定义线程池的参数创建

5、谈谈ThreadLocal的理解 

### C++多线程常见的面试问题及答案 #### 1. **什么是竞争条件?如何解决它?** 竞争条件是指当多个线程访问共享资源并至少有一个线程修改该资源时,可能导致不可预测的结果。这种情况下,程序的行为取决于线程调度的时间顺序。 解决方案通常包括使用互斥锁(mutex)、信号量或其他同步机制来保护共享资源的访问[^2]。通过这些工具,可以确保同一时间只有一个线程能访问临界区代码。 #### 2. **解释一下`std::thread`的基本用法。** `std::thread` 是 C++11 中引入的一个类,用于表示和管理线程。可以通过传递一个可调用对象(函数、lambda 表达式或 functor)给 `std::thread` 的构造函数来启动新线程。 下面是一个简单的例子展示如何创建和加入线程: ```cpp #include <iostream> #include <thread> void threadFunction(int id) { std::cout << "Thread ID: " << id << "\n"; } int main() { std::thread t(threadFunction, 42); t.join(); // 等待线程完成 } ``` #### 3. **描述`std::mutex`的作用以及如何使用它防止数据竞争。** `std::mutex` 提供了一个基本的互斥锁功能,允许程序员控制对共享资源的访问。要使用 `std::mutex` 来防止数据竞争,可以在访问共享变量之前锁定 mutex,在完成后解锁。 示例代码如下: ```cpp #include <iostream> #include <thread> #include <mutex> std::mutex mtx; int sharedVariable = 0; void incrementSharedVar() { mtx.lock(); ++sharedVariable; mtx.unlock(); } int main() { std::thread t1(incrementSharedVar); std::thread t2(incrementSharedVar); t1.join(); t2.join(); std::cout << "Final value of shared variable is " << sharedVariable << '\n'; } ``` 上述代码展示了如何利用 `std::mutex` 锁定和释放共享变量的操作。 #### 4. **什么是死锁?举例说明可能引发死锁的情况及其预防措施。** 死锁发生在两个或更多线程互相等待对方持有的资源而无法继续运行的情况下。例如: - 线程 A 持有 Resource X 并请求 Resource Y; - 同时,线程 B 持有 Resource Y 并请求 Resource X。 这种情况会导致两者都无法前进。为了避免死锁,常用的方法包括按固定顺序加锁、减少持有锁的时间长度或者采用无阻塞算法设计。 #### 5. **C++中的原子操作是什么?为什么它们重要?** 原子操作指的是那些即使在多处理器环境下也能作为一个整体被执行而不被打断的操作。这意味着如果某个线程正在执行这样的操作,则其他任何线程都不能干扰这一过程直到结束。 在 C++ 中,头文件 `<atomic>` 提供了支持原子类型的模板类 `std::atomic<T>` 。这对于实现高效且安全的并发程序非常重要,因为它们消除了对于某些简单算术运算的需求额外显式的同步原语[^4]。 --- ###
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学会用脚编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值