java线程面试题之--两个线程,子线程10次,主线程5次,子线程10次,主线程5次,如此往复50次

本文提供了一个使用Java实现的线程间通信案例。通过两种方法实现:一是传统的wait和notify方式;二是利用ReentrantLock和Condition条件变量的方式。案例中主线程和子线程交替执行,实现了任务间的协调。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.thread;

//两个线程,子线程10次,主线程5次,子线程10次,主线程5次,如此往复50次

//首先实现互斥,然后实现通信
public class TranditionalThreadCommunication {

	final Business business = new Business();

	public static void main(String[] args) {
		new TranditionalThreadCommunication().init();
	}

	private void init() {
		new Thread(new Runnable() {

			@Override
			public void run() {
				for(int i=0;i<50;i++)
				{
				  business.main();
				}
			}
		}).start();

		for(int i=0;i<50;i++)
		{
			business.sub();
		}
	}

	class Business {
		private Boolean isShouldSub = true;

		public synchronized void main() {
			if (!isShouldSub) {
				for (int i = 0; i < 5; i++) {
					System.out.println("主线程第" + i + "次");
				}
				isShouldSub = true;
				this.notify();
			} else {
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		public synchronized void sub() {
			if (isShouldSub) {
				for (int j = 0; j < 10; j++) {
					System.out.println("子线程第" + j + "次");
				}
				isShouldSub = false;
				this.notify();
			} else {
				try {
					this.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}
利用condition和lock实现互斥和通信

package com.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

//利用condition和lock实现互斥和通信
//两个线程,子线程10次,主线程5次,子线程10次,主线程5次,如此往复50次

//首先实现互斥,然后实现通信
public class ConditionCommunication {

	final Business business = new Business();

	public static void main(String[] args) throws InterruptedException {
		new ConditionCommunication().init();
	}

	private void init() throws InterruptedException {
		new Thread(new Runnable() {

			@Override
			public void run() {
				for (int i = 0; i < 50; i++) {
					try {
						business.main();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}).start();

		for (int i = 0; i < 50; i++) {
			business.sub();
		}
	}

	class Business {

		private Boolean isShouldSub = true;
		ReentrantLock lock = new ReentrantLock();
		Condition condition=lock.newCondition();

		public void main() throws InterruptedException {
			try {
				lock.lock();
				if (isShouldSub) {
					System.out.println("主线程等待");
					condition.await();
				} else {
					System.out.println("主线程锁上了!");
					for (int i = 0; i < 5; i++) {
						System.out.println("主线程第" + i + "次");
					}
					isShouldSub = true;
					condition.signal();
				}
			} finally {
				System.out.println("主线程解锁");
				lock.unlock();
			}

		}

		public void sub() throws InterruptedException {
			try {
				lock.lock();
				if (!isShouldSub) {
					System.out.println("子线程等待");
					condition.await();
				} else {
					System.out.println("子线程锁上了!");
					for (int j = 0; j < 10; j++) {
						System.out.println("子线程第" + j + "次");
					}
					isShouldSub = false;
					condition.signal();
				}
			} finally {
				System.out.println("子线程解锁");
				lock.unlock();
			}
		}
	}
}


<think>嗯,用户想了解Android多线程相关的面试知识点,特别是常见问题与解答。我需要先整理一下Android多线程的核心内容,比如线程的创建方式、Handler机制、AsyncTask、线程池、线程同步这些应该是重点。 首先,用户提到的引用[2]里提到了继承Thread类和实现Runnable接口,这两种创建线程的方式。需要详细说明两者的区别,比如Runnable更适合资源共享,避免单继承的限制。然后,用户可能还会问到这两种方式的优缺点,以及在实际开发中的选择依据。 接下来是Handler机制,这是Android中处理线程间通信的重要部分。引用[1]提到了Message、MessageQueue、Looper和Handler,需要解释它们之间的关系。比如,每个线程只能有一个Looper,负责从MessageQueue中取出消息,然后由Handler处理。这里可能会涉及到主线程子线程的切换,以及如何避免内存泄漏,比如持有Activity的引用导致无法释放。 然后是AsyncTask,虽然现在可能已经被官方推荐的其他方式取代,但面试中还是可能会问到。需要说明它的三个泛型参数和几个回调方法,比如doInBackground和onPostExecute,还有它的内部线程池机制。同时要提到AsyncTask的缺点,比如在Activity销毁时可能引起的问题,以及在Android 3.0后的串行执行问题。 线程池也是必问的点,Java提供的ThreadPoolExecutor以及Android中的便捷类,比如Executors.newFixedThreadPool等。需要解释核心参数,核心线程数、最大线程数、存活时间和工作队列。同时,线程池的好处,比如减少资源消耗,提高响应速度,管理线程的生命周期。 线程同步方面,synchronized关键字和ReentrantLock的区别,volatile的作用,以及ConcurrentHashMap这样的线程安全集合。引用[3]提到了fail-fast机制,可能和线程安全的集合相关,需要说明如何避免ConcurrentModificationException,比如使用CopyOnWriteArrayList或者在迭代时加锁。 还有可能会问到主线程子线程的交互,比如不能在主线程执行耗时操作,否则会引发ANR,以及如何通过Handler或runOnUiThread来更新UI。此外,IntentService和WorkManager这样的高级主题也可能被提及,需要简要说明它们的作用和使用场景。 用户提供的引用[4]提到了Adapter的getView方法中利用缓存,这可能和列表的异步加载有关,比如在子线程加载图片然后通过Handler更新UI,但这里可能更多涉及ListView或RecyclerView的优化,不过用户的问题集中在多线程,所以可能需要关联到线程池管理异步任务。 还要注意用户的需求是面试常见问题,所以回答需要结构清晰,分点列出问题并提供简明解答。可能还要考虑最新的Android开发趋势,比如协程(Kotlin)和LiveData的结合使用,但用户的问题可能更偏向传统Java线程,所以需要平衡。 最后,确保回答中的代码示例正确,比如Handler的使用,或者synchronized块的例子。同时,引用用户提供的引用,比如引用[1]到[4],但用户给出的引用中有部分内容可能不直接相关,比如AIDL和fail-fast,但需要合理融入,比如在讲线程安全时提到fail-fast机制。 总结一下,回答的结构应该是先介绍多线程的基本概念和创建方式,然后深入Handler机制,接着是AsyncTask、线程池、线程同步,最后是其他高级主题和常见面试问题。确保每个部分都有对应的常见问题,并引用相关的资料来支持答案的准确性。</think># Android多线程面试知识点解析 ## 一、线程基础与创建方式 1. **线程创建方法** - **继承Thread类**:需重写`run()`方法,通过`start()`启动线程 - **实现Runnable接口**:更灵活,避免单继承限制,推荐使用[^2] ```java class MyRunnable implements Runnable { public void run() { // 耗时操作 } } new Thread(new MyRunnable()).start(); ``` - **实现Callable接口**:可返回结果和抛出异常 2. **线程状态转换** - NEW -> RUNNABLE -> RUNNING -> BLOCKED/WAITING -> TERMINATED ## 二、核心通信机制:Handler 1. **四要素关系** - **Message**:数据载体 - **MessageQueue**:消息队列(单向链表) - **Looper**:轮询器(每个线程唯一,通过`Looper.prepare()`创建) - **Handler**:消息处理器[^1] 2. **主线程消息循环** ```java // 子线程发送消息 new Thread(() -> { Message msg = handler.obtainMessage(); msg.sendToTarget(); }).start(); // 主线程处理 Handler handler = new Handler(Looper.getMainLooper()) { public void handleMessage(Message msg) { // 更新UI } }; ``` ## 三、异步任务框架 1. **AsyncTask**(已过时但需了解) ```java class MyTask extends AsyncTask<Params, Progress, Result> { protected Result doInBackground(Params... params) { /* 后台操作 */ } protected void onPostExecute(Result result) { /* UI更新 */ } } ``` - 缺点:内存泄漏风险、版本兼容性问题(3.0后默认串行) 2. **替代方案** - **协程**(Kotlin) - **RxJava** - **ExecutorService** ## 四、线程池优化(重点) 1. **ThreadPoolExecutor参数** ```java ExecutorService pool = new ThreadPoolExecutor( corePoolSize, // 核心线程数 maximumPoolSize, // 最大线程数 keepAliveTime, // 空闲存活时间 TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>() // 任务队列 ); ``` 2. **四种常用线程池** - `newFixedThreadPool`:固定大小 - `newCachedThreadPool`:弹性扩容 - `newScheduledThreadPool`:定时任务 - `newSingleThreadExecutor`:单线程顺序执行 ## 五、线程同步与安全 1. **同步机制** - **synchronized**:方法级/代码块锁 - **ReentrantLock**:可中断锁、公平锁 - **volatile**:保证可见性,非原子性 2. **线程安全集合** - `ConcurrentHashMap`:分段锁技术 - `CopyOnWriteArrayList`:写时复制 - 注意**fail-fast机制**:遍历时修改会抛出`ConcurrentModificationException`[^3] ## 六、高级应用场景 1. **IntentService** - 自动管理线程的Service - 内部通过HandlerThread实现 2. **HandlerThread** - 自带Looper的线程类 ```java HandlerThread handlerThread = new HandlerThread("MyHandlerThread"); handlerThread.start(); Handler handler = new Handler(handlerThread.getLooper()); ``` 3. **WorkManager** - 后台任务调度框架(周期性任务/约束条件)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值