在GWT客户端模拟缺失的java.lang.Thread类的实现方案咨询
问题描述
动机
按照Java并发编程规范,在抛出CustomInterruptedException前需要调用Thread.currentThread().interrupt();,以此在catch块中传递中断状态。为避免重复编写这两行代码,希望封装成通用工具函数:
Thread.currentThread().interrupt();throw new CustomInterruptedException("This thread was interrupted...");
问题
GWT客户端未实现java.lang.Thread类,但不想为客户端和服务器端分别实现该工具函数。
疑问
是否有办法在GWT客户端模拟java.lang.Thread类的存在?
解决方案
1. 利用GWT的JRE模拟机制自定义Thread实现
GWT允许通过JRE Emulation机制替换或补充JRE类的实现。你可以在客户端源码目录下创建java/lang/Thread.java(包路径必须完全匹配),实现核心方法即可:
package java.lang; public class Thread { // 用ThreadLocal模拟中断状态(GWT客户端为单线程,仅做逻辑标记) private static final ThreadLocal<Boolean> interruptedFlag = new ThreadLocal<Boolean>() { @Override protected Boolean initialValue() { return false; } }; public static Thread currentThread() { return new Thread(); } public void interrupt() { interruptedFlag.set(true); } public boolean isInterrupted() { return interruptedFlag.get(); } // 可选:实现静态方法清除中断状态 public static boolean interrupted() { boolean flag = interruptedFlag.get(); interruptedFlag.set(false); return flag; } }
GWT编译时会优先使用这个客户端实现,服务器端则自动使用JDK原生Thread类,你的通用工具函数可以直接调用相关方法,无需区分环境。
2. 封装抽象层实现跨环境兼容
如果不想直接模拟JRE类,可以定义抽象工具接口,分别提供客户端和服务器端实现:
定义核心接口
public interface ThreadInterruptHandler { void interruptCurrentThreadAndThrow() throws CustomInterruptedException; }
服务器端实现
public class ServerThreadInterruptHandler implements ThreadInterruptHandler { @Override public void interruptCurrentThreadAndThrow() throws CustomInterruptedException { Thread.currentThread().interrupt(); throw new CustomInterruptedException("This thread was interrupted..."); } }
客户端实现
public class ClientThreadInterruptHandler implements ThreadInterruptHandler { private static final ThreadLocal<Boolean> interrupted = new ThreadLocal<>(); @Override public void interruptCurrentThreadAndThrow() throws CustomInterruptedException { interrupted.set(true); throw new CustomInterruptedException("This thread was interrupted..."); } // 供客户端逻辑检查中断状态 public static boolean isCurrentThreadInterrupted() { return Boolean.TRUE.equals(interrupted.get()); } }
配置GWT延迟绑定
在GWT模块文件(.gwt.xml)中添加绑定规则,自动根据环境选择实现类:
<replace-with class="com.yourpackage.ClientThreadInterruptHandler"> <when-type-is class="com.yourpackage.ThreadInterruptHandler"/> <when-property-is name="gwt.client" value="true"/> </replace-with> <replace-with class="com.yourpackage.ServerThreadInterruptHandler"> <when-type-is class="com.yourpackage.ThreadInterruptHandler"/> <when-property-is name="gwt.client" value="false"/> </replace-with>
业务代码中直接获取实例使用:
ThreadInterruptHandler handler = GWT.create(ThreadInterruptHandler.class); handler.interruptCurrentThreadAndThrow();
3. 在通用函数中直接做环境判断
如果不想增加额外类,可在工具函数中通过GWT.isClient()区分环境:
public static void interruptAndThrow() throws CustomInterruptedException { if (GWT.isClient()) { ClientInterruptMarker.markInterrupted(); } else { Thread.currentThread().interrupt(); } throw new CustomInterruptedException("This thread was interrupted..."); } // 客户端中断状态标记辅助类 class ClientInterruptMarker { private static final ThreadLocal<Boolean> interrupted = new ThreadLocal<>(); public static void markInterrupted() { interrupted.set(true); } public static boolean isInterrupted() { return Boolean.TRUE.equals(interrupted.get()); } }
这种方式最简洁,但客户端的中断状态需要你自己在业务逻辑中主动检查使用。
内容的提问来源于stack exchange,提问作者Tugalsan Karabacak
相关产品推荐
相关产品推荐

