摸同桌小内内摸出了水虽然也不错无须声明一个 class
发布日期:2022-09-23 04:31    点击次数:147
国产videos爆乳摸同桌小内内摸出了水

本文转载自微信公众号「 crossoverJie」,作家crossoverJie  。转载本文请接头 crossoverJie公众号。

在这篇著作中你将会学习到一些你可能没听过但有用的 Java 特色,这些是我个人常用的一些特色或者是从其他著作中学习到的,重心是情切 API 而不是言语自身。

蔓延队伍

人所共知,在 Java 中有好多类型的聚积不错使用,但你传闻过 DelayQueue 吗?它是一个特定类型的聚积,允许咱们基于延频频候对数据排序,这是一个格外挑升思的类,它杀青了 BlockingQueue 接口,惟有当数据逾期后才智从队伍里取出。

使用它的第一步,你的 class 需要杀青 Delayed 接口中的 getDelay 法子,虽然也不错无须声明一个 class,使用 Record 亦然不错的。

这是 Java14 的新特色

public record DelayedEvent(long startTime, String msg) implements Delayed {      public long getDelay(TimeUnit unit) {         long diff = startTime - System.currentTimeMillis();         return unit.convert(diff, TimeUnit.MILLISECONDS);     }      public int compareTo(Delayed o) {         return (int) (this.startTime - ((DelayedEvent) o).startTime);     }  } 

假定咱们需要一个延时 10s 取出的数据,咱们只需要放入一个比现时时候多 10s 的任务即可。

final DelayQueue<DelayedEvent> delayQueue = new DelayQueue<>(); final long timeFirst = System.currentTimeMillis() + 10000; delayQueue.offer(new DelayedEvent(timeFirst, "1")); log.info("Done"); log.info(delayQueue.take().msg()); 

最终输出如下:

时候局面的日历

这个特色可能对大部分人来说没什么用,但浑朴说我个人格外可爱;岂论如何说 Java 8 在时候 API 上校正了好多。从这个版块最先大约你不再需要其他任何膨大库了。

你能猜想嘛,从 Java 16 中你以至不错用尺度库默示一天内的日历了, 酵素比如 “in the morning” “in the afternoon” ,这是一个新的局面语句 B。

String s = DateTimeFormatter   .ofPattern("B")   .format(LocalDateTime.now()); System.out.println(s); 

以下是我的输出,具体和你现时时候接头。

你可能会想为什么会是调用 “B” 呢,这照实看起来不太直觉,通过下表也许能解答狐疑:

Stamped Lock

在我看来,并发包是 Java 中最挑升思的包之一,同期又很少被建树者老到摆布,很是是恒久使用 web 建树框架的建树者。

有若干人仍是使用过 Lock 呢?相干于 synchronized 来说这是一种更纯真是线程同步机制。

从 Java8 最先你不错使用一种新的锁:StampedLock.StampedLock,能够替代 ReadWriteLock。

假定面前有两个线程,一个线程更新金额、一个线程读取余额;更新余额的线程领先需要读取金额,大大香蕉伊人久久爱再多线程的情况下需要某种同步机制(否则更新数据会发生虚假),第二个线程用乐观锁的神志读取余额。

StampedLock lock = new StampedLock(); Balance b = new Balance(10000); Runnable w = () -> {    long stamp = lock.writeLock();    b.setAmount(b.getAmount() + 1000);    System.out.println("Write: " + b.getAmount());    lock.unlockWrite(stamp); }; Runnable r = () -> {    long stamp = lock.tryOptimisticRead();    if (!lock.validate(stamp)) {       stamp = lock.readLock();       try {          System.out.println("Read: " + b.getAmount());       } finally {          lock.unlockRead(stamp);       }    } else {       System.out.println("Optimistic read fails");    } }; 

面前更新和读取的都用 50 个线程来进行测试,最终的余额将会等于 60000.

ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 50; i++) {    executor.submit(w);    executor.submit(r); } 
并发累加器

锁并并不是并发包中惟一挑升思的特色,并发累加器也不异意旨;它不错凭据咱们提供的函数更新数据;再多线程更新数据的场景下,LongAccumulator 是比 AtomicLong 更优的聘用。

面前让咱们来望望具体如何使用,咱们需要两个参数进行启动化;第一个是用于累加筹算的函数,常常是一个 sum 函数,第二个参数则是累加筹算的启动化值。

接下来咱们用 10000 算作启动值来创建一个 LongAccumulator,最终效果是若干?其实效果与上文调换,都是 60000,但此次咱们并莫得使用锁。

LongAccumulator balance = new LongAccumulator(Long::sum, 10000L); Runnable w = () -> balance.accumulate(1000L);  ExecutorService executor = Executors.newFixedThreadPool(50); for (int i = 0; i < 50; i++) {    executor.submit(w); }  executor.shutdown(); if (executor.awaitTermination(1000L, TimeUnit.MILLISECONDS))    System.out.println("Balance: " + balance.get()); assert balance.get() == 60000L; 
数组的二分查找

假定咱们想在一个排序列表中插入一个新元素,不错使用 Arrays.binarySearch() 函数,当这个 key 存在时将会复返 key 场地的索引,淌若不存在时将会复返插入的位置-(insertion point)-1。

binarySearch 是 Java 中格外浅薄且有用的查询法子。

底下的这个例子中,对复返效果取反便能的到索引位置。

int[] t = new int[] {1, 2, 4, 5}; int x = Arrays.binarySearch(t, 3);  assert ~x == 2; 

负数的二进制是以正数的补码默示,对一个数取反+1 就等于补码,是以这里告成取反就等于 Arrays.binarySearch() 不存在时的复返值了。

Bit Set

淌若你需要对二进制数组进行操作你会如何做?用 boolean[] 布尔数组?

有一种更高效又更省内存的神志,那即是 BitSet。它允许咱们存储和操作 bit 数组,与 boolean[] 比较可省 8 倍的内存;也不错使用 and/or/xor 等逻辑操作。

假定咱们面前有两个 bit 数组,咱们需要对他们进行 xor 运算;咱们需要创建两个 BitSet 实例,然后调用 xor 函数。

BitSet bs1 = new BitSet(); bs1.set(0); bs1.set(2); bs1.set(4); System.out.println("bs1 : " + bs1);  BitSet bs2 = new BitSet(); bs2.set(1); bs2.set(2); bs2.set(3); System.out.println("bs2 : " + bs2);  bs2.xor(bs1); System.out.println("xor: " + bs2); 

最终的输出效果如下: