6、JSR292与InvokeDynamic
JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform,支持在JVM上运行动态类型语言。在字节码层面支持了InvokeDynamic。
方法句柄MethodHandle
public class ThreadPoolManager { private final ScheduledExecutorService stpe = Executors .newScheduledThreadPool(2); private final BlockingQueue<WorkUnit<String>> lbq; public ThreadPoolManager(BlockingQueue<WorkUnit<String>> lbq_) { lbq = lbq_; } public ScheduledFuture<?> run(QueueReaderTask msgReader) { msgReader.setQueue(lbq); return stpe.scheduleAtFixedRate(msgReader, 10, 10, TimeUnit.MILLISECONDS); } private void cancel(final ScheduledFuture<?> hndl) { stpe.schedule(new Runnable() { public void run() { hndl.cancel(true); } }, 10, TimeUnit.MILLISECONDS); } /** * 使用传统的反射api */ public Method makeReflective() { Method meth = null; try { Class<?>[] argTypes = new Class[]{ScheduledFuture.class}; meth = ThreadPoolManager.class.getDeclaredMethod("cancel", argTypes); meth.setAccessible(true); } catch (IllegalArgumentException | NoSuchMethodException | SecurityException e) { e.printStackTrace(); } return meth; } /** * 使用代理类 * @return */ public CancelProxy makeProxy() { return new CancelProxy(); } /** * 使用Java7的新api,MethodHandle * invoke virtual 动态绑定后调用 obj.xxx * invoke special 静态绑定后调用 super.xxx * @return */ public MethodHandle makeMh() { MethodHandle mh; MethodType desc = MethodType.methodType(void.class, ScheduledFuture.class); try { mh = MethodHandles.lookup().findVirtual(ThreadPoolManager.class, "cancel", desc); } catch (NoSuchMethodException | IllegalAccessException e) { throw (AssertionError) new AssertionError().initCause(e); } return mh; } public static class CancelProxy { private CancelProxy() { } public void invoke(ThreadPoolManager mae_, ScheduledFuture<?> hndl_) { mae_.cancel(hndl_); } } }
- 调用invoke
public class ThreadPoolMain { /** * 如果被继承,还能在静态上下文寻找正确的class */ private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private ThreadPoolManager manager; public static void main(String[] args) { ThreadPoolMain main = new ThreadPoolMain(); main.run(); } private void cancelUsingReflection(ScheduledFuture<?> hndl) { Method meth = manager.makeReflective(); try { System.out.println("With Reflection"); meth.invoke(hndl); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } } private void cancelUsingProxy(ScheduledFuture<?> hndl) { CancelProxy proxy = manager.makeProxy(); System.out.println("With Proxy"); proxy.invoke(manager, hndl); } private void cancelUsingMH(ScheduledFuture<?> hndl) { MethodHandle mh = manager.makeMh(); try { System.out.println("With Method Handle"); mh.invokeExact(manager, hndl); } catch (Throwable e) { e.printStackTrace(); } } private void run() { BlockingQueue<WorkUnit<String>> lbq = new LinkedBlockingQueue<>(); manager = new ThreadPoolManager(lbq); final QueueReaderTask msgReader = new QueueReaderTask(100) { @Override public void doAction(String msg_) { if (msg_ != null) System.out.println("Msg recvd: " + msg_); } }; ScheduledFuture<?> hndl = manager.run(msgReader); cancelUsingMH(hndl); // cancelUsingProxy(hndl); // cancelUsingReflection(hndl); } }
7、Path接口(重要接口更新)
Path
public class PathUsage { public void usePath() { Path path1 = Paths.get("folder1", "sub1"); Path path2 = Paths.get("folder2", "sub2"); path1.resolve(path2); //folder1\sub1\folder2\sub2 path1.resolveSibling(path2); //folder1\folder2\sub2 path1.relativize(path2); //..\..\folder2\sub2 path1.subpath(0, 1); //folder1 path1.startsWith(path2); //false path1.endsWith(path2); //false Paths.get("folder1/./../folder2/my.text").normalize(); //folder2\my.text } /** * @param args the command line arguments */ public static void main(String[] args) { PathUsage usage = new PathUsage(); usage.usePath(); } }
- DirectoryStream
public class ListFile { public void listFiles() throws IOException { Path path = Paths.get(""); try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.*")) { for (Path entry: stream) { //使用entry System.out.println(entry); } } } /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { ListFile listFile = new ListFile(); listFile.listFiles(); } }
- Files
public class FilesUtils { public void manipulateFiles() throws IOException { Path newFile = Files.createFile(Paths.get("new.txt").toAbsolutePath()); List<String> content = new ArrayList<String>(); content.add("Hello"); content.add("World"); Files.write(newFile, content, Charset.forName("UTF-8")); Files.size(newFile); byte[] bytes = Files.readAllBytes(newFile); ByteArrayOutputStream output = new ByteArrayOutputStream(); Files.copy(newFile, output); Files.delete(newFile); } /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { FilesUtils fu = new FilesUtils(); fu.manipulateFiles(); } }
- WatchService
public class WatchAndCalculate { public void calculate() throws IOException, InterruptedException { WatchService service = FileSystems.getDefault().newWatchService(); Path path = Paths.get("").toAbsolutePath(); path.register(service, StandardWatchEventKinds.ENTRY_CREATE); while (true) { WatchKey key = service.take(); for (WatchEvent<?> event : key.pollEvents()) { Path createdPath = (Path) event.context(); createdPath = path.resolve(createdPath); long size = Files.size(createdPath); System.out.println(createdPath + " ==> " + size); } key.reset(); } } /** * @param args the command line arguments */ public static void main(String[] args) throws Throwable { WatchAndCalculate wc = new WatchAndCalculate(); wc.calculate(); } }
8、fork/join计算框架
Java7提供的一个用于并行执行任务的框架,是一个把大任务分割成若干个小任务,最终汇总每个小任务结果后得到大任务结果的框架。
该框架为Java8的并行流打下了坚实的基础