Java线程与同步方法未按预期执行,求Android环境下解决方案
问题分析与解决方案
我来帮你拆解下当前代码的问题,以及对应的修复方案:
核心问题根源
你遇到的同步失效主要有两个原因:
- wait()方法会释放锁:服务类中
synchronized(singularProcessor.context)块内调用的wait(),会自动释放context对象的锁。这就导致第一个线程还在synchronized(context)块中sleep时,第二个新线程能直接获取到context锁,进入doNotDisturbMe()方法并行执行。 - 状态标记不共享:每个
Singular_Processor实例的needWait是独立的实例变量,第二个线程初始化时needWait为false,服务类的第二次调用直接跳过等待逻辑,启动新线程。
解决方案
方案1:使用类级锁强制串行执行
给Singular_Processor添加一个静态锁对象,让所有线程实例共享同一把锁,确保同一时间只有一个线程能进入doNotDisturbMe()方法:
class Singular_Processor extends Thread { private static final String TAG = "Singular_Processor"; // 类级静态锁,所有线程实例共享 private static final Object PROCESSOR_LOCK = new Object(); final Context context; Singular_Processor(Context context) { this.context = context; } @Override public void run() { try { doNotDisturbMe(); } catch (Exception e) { e.printStackTrace(); } } private void doNotDisturbMe() { synchronized (PROCESSOR_LOCK) { try { Log.d(TAG, "RUNNING THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); Thread.sleep(10000); Log.d(TAG, "COMPLETED THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "EXCEPTION THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } } } }
服务类调用代码可以简化(如果不需要等待线程执行完成,直接启动即可):
final Singular_Processor singularProcessor = new Singular_Processor(this); singularProcessor.start(); // 若需要等待当前线程执行完再继续,可调用join() // singularProcessor.join();
方案2:修复原有同步逻辑(保留context锁)
如果你必须依赖context作为锁,需要将状态标记改为静态共享,并调整服务类的等待逻辑:
修改Singular_Processor类
class Singular_Processor extends Thread { private static final String TAG = "Singular_Processor"; final Context context; // 改为静态变量,所有线程共享执行状态 private static boolean isProcessing = false; Singular_Processor(Context context) { this.context = context; } @Override public void run() { try { doNotDisturbMe(); } catch (Exception e) { e.printStackTrace(); } } private void doNotDisturbMe() { synchronized (context) { try { isProcessing = true; Log.d(TAG, "RUNNING THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); Thread.sleep(10000); Log.d(TAG, "COMPLETED THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } catch (Exception e) { e.printStackTrace(); Log.d(TAG, "EXCEPTION THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } finally { isProcessing = false; context.notifyAll(); } } } // 提供静态方法暴露执行状态 public static boolean isProcessing() { return isProcessing; } }
修改服务类调用逻辑
// 服务类中调用代码 synchronized (this) { // 等待上一个线程执行完成 while (Singular_Processor.isProcessing()) { wait(); } final Singular_Processor singularProcessor = new Singular_Processor(this); singularProcessor.start(); }
方案3:使用SingleThreadExecutor(推荐)
如果你的核心需求是确保任务串行执行,Java提供的SingleThreadExecutor是最简洁可靠的方案,它会自动将所有提交的任务排队,完全不需要手动处理锁和等待逻辑:
// 在服务类中初始化全局唯一的单线程执行器 private final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor(); // 服务类中的调用方法 public void startProcessing() { singleThreadExecutor.submit(() -> { try { Log.d("Singular_Processor", "RUNNING THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); Thread.sleep(10000); Log.d("Singular_Processor", "COMPLETED THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } catch (Exception e) { e.printStackTrace(); Log.d("Singular_Processor", "EXCEPTION THE THREAD ID : " + Thread.currentThread().getId() + ".. \n"); } }); }
内容的提问来源于stack exchange,提问作者Rushikant Pawar
相关产品推荐
相关产品推荐

