当前位置: 首页 > news >正文

java类库

第一行索拉卡富家大室丽枫酒店算啦科技离开第三方都是放假了扩大时就发了肯定是附件离开到时间了肯定是发了肯定是就打了放假了快递师傅大点了饭结算单离开发生的

第二行收款方叫哦if文件妇女,细思恐极东方丽都记录卡发撒记录卡司法鉴定司法鉴定刷卡机打撒凉快点精神分裂开始凉快点凉快点放假了肯定是放假了肯定是


java.time

LocalDate

public class LocalDateDemo {public static void main(String[] args) {LocalDate now = LocalDate.now();now.plusYears(1); // 加一年now.minusMonths(1); // 减一个月now.withYear(2020); // 修改月now.isBefore(now.plusDays(1)); // true}
}

LocalTime

public class LocalTimeDemo {public static void main(String[] args) {LocalTime now = LocalTime.now();now.plusHours(1); // 加一小时now.minusMinutes(2); // 减两分钟now.withSecond(1); // 修改秒now.isBefore(now.plusHours(1)); // true}
}

LocalDateTime

public class LocalDateTimeDemo {public static void main(String[] args) {LocalDateTime now = LocalDateTime.now();now.plusYears(1); // 加一年now.minusHours(1); // 减一小时now.withMonth(2); // 修改月now.isBefore(now.plusDays(1)); // trueDateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");String format = dtf.format(now); // 2025-10-04 14:08:00}
}

Duration

public class DurationDemo {public static void main(String[] args) throws InterruptedException {Instant now = Instant.now();TimeUnit.SECONDS.sleep(3);Duration duration = Duration.between(now, Instant.now());duration.toMillis(); // 3000 ms}
}

java.rmi

远程方法调用(remote method invoke),客户端与服务端的包路径、接口名必须完全相同。

server

SendMsg

public interface SendMsg extends Remote {void send() throws RemoteException;
}

WeChat

public class WeChat extends UnicastRemoteObject implements SendMsg {public WeChat() throws RemoteException {}@Overridepublic void send() throws RemoteException {System.out.println("微信发送消息");}}

QQ

public class QQ extends UnicastRemoteObject implements SendMsg {public QQ() throws RemoteException {}@Overridepublic void send() throws RemoteException {System.out.println("QQ发送消息");}}

RMIServer

public class RMIServer {public static void main(String[] args) throws RemoteException, AlreadyBoundException {Registry registry = LocateRegistry.createRegistry(8080);registry.bind("sendMsg", new QQ());}
}

client

SendMsg

public interface SendMsg extends Remote {void send() throws RemoteException;
}

RMIClient

public class RMIClient {public static void main(String[] args) throws RemoteException, NotBoundException {Registry registry = LocateRegistry.getRegistry("127.0.0.1", 8080);SendMsg sendMsg = (SendMsg) registry.lookup("sendMsg");sendMsg.send();}
}

java.math

BigDecimal

public class BigDecimalDemo {public static void main(String[] args) {BigDecimal ten = new BigDecimal("10");BigDecimal three = new BigDecimal("3");String add = ten.add(three).toPlainString(); // 13String subtract = ten.subtract(three).toPlainString(); // 7String multiply = ten.multiply(three).toPlainString(); // 30String divide = ten.divide(three, 3, RoundingMode.HALF_UP).toPlainString(); // 3.333 四舍五入}
}

java.sql

public class JDBCDemo {public static void main(String[] args) throws SQLException {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo?useSSL=false","root","jrbjrb811");connection.setAutoCommit(false); // 开启事务preparedStatement = connection.prepareStatement("select * from demo_student where stu_age > ?");preparedStatement.setInt(1, 18);resultSet = preparedStatement.executeQuery();while (resultSet.next()) {System.out.println(resultSet.getString("stu_name") + " => " + resultSet.getInt("stu_age"));}connection.commit(); // 事务提交} catch (Exception e) {e.printStackTrace();connection.rollback(); // 事务回滚} finally {if (resultSet != null) {resultSet.close();}if (preparedStatement != null) {preparedStatement.close();}if (connection != null) {connection.close();}}}
}

java.io

[外链图片转存中…(img-XxRKqTHA-1760397622179)]

输入流:从磁盘到内存。输出流:从内存到磁盘。

字节流:以字节为单位读写数据。字符流:以字符为单位读写数据。

File

FileInputStream

FileOutputStream

flush()

拷贝文件夹

public class JavaIoDemo {public static void main(String[] args) throws Exception {File src = new File("D:\\Gitee\\java\\src");File dest = new File("D:\\Gitee\\java\\dest");copyDir(src, dest);}private static void copyDir(File src, File dest) throws Exception {if (!dest.exists()) {dest.mkdirs();}for (File file : src.listFiles()) {if (file.isFile()) {FileInputStream fis = new FileInputStream(file);FileOutputStream fos = new FileOutputStream(new File(dest, file.getName()));byte[] bytes = new byte[1024];int length;while ((length = fis.read(bytes)) != -1) {fos.write(bytes, 0, length);}fos.close();fis.close();} else if (file.isDirectory()) {copyDir(file, new File(dest, file.getName()));}}}
}

FileReader

FileWriter

BufferedInputStream

缓冲流在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数。

BufferedOutputStream

BufferedReader

BufferedWriter

InputStreamReader

将字节流以指定的编码转为字符流读。

OutputStreamWriter

将字符流以指定的编码转为字节流写。

[外链图片转存中…(img-1RA3wprP-1760397622181)]

ObjectInputStream

ObjectOutputStream

实现对象的持久存储。

java.util.concurrent

AtomicInteger

Unsafe类:提供的方法可以直接访问内存、线程。

属性:Unsafe、int value

通过Unsafe方法中的CAS循环,保证int类型值的原子操作。

public class AtomicIntegerDemo {static int num = 0;static AtomicInteger ai = new AtomicInteger(0);public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(3);CountDownLatch countDownLatch = new CountDownLatch(3);for (int i = 0; i < 3; i++) {threadPool.execute(() -> {for (int j = 0; j < 10000; j++) {//num++;ai.incrementAndGet();}countDownLatch.countDown();});}countDownLatch.await();//System.out.println(num);System.out.println(ai.get());}}

LongAdder

以空间换时间,内部有多个单元格数组,add时,可能在数组的不同位置进行CAS,避免了CAS的冲突,提高的CAS的成功率。
相较于AtomicInteger,性能高(CAS成功率高)、但内存开销大。

AtomicBoolean

属性:Unsafe、int value(0、1代表true、false)

保证boolean类型值的原子操作。

// 优雅的停止线程
public class AtomicBooleanDemo {public static void main(String[] args) throws InterruptedException {ABRunnable abRunnable = new ABRunnable();new Thread(abRunnable).start();TimeUnit.SECONDS.sleep(3);abRunnable.stop();}
}@Data
class ABRunnable implements Runnable {private AtomicBoolean ab = new AtomicBoolean(true);@SneakyThrows@Overridepublic void run() {System.out.println(LocalTime.now());while (ab.get()) {System.out.println("do something");TimeUnit.SECONDS.sleep(1);}System.out.println(LocalTime.now());}public void stop() {ab.compareAndSet(true, false);}
}

AtomicReference

属性:Unsafe、Object

实现对一个对象引用的原子操作。

public class AtomicReferenceDemo {public static void main(String[] args) throws InterruptedException {ARObj arObj = new ARObj("张三", 0);AtomicReference<ARObj> ar = new AtomicReference<>(arObj);AtomicInteger ai = new AtomicInteger(0);ExecutorService threadPool = Executors.newFixedThreadPool(3);CountDownLatch countDownLatch = new CountDownLatch(3);for (int i = 0; i < 3; i++) {threadPool.execute(() -> {for (int j = 0; j < 10000; j++) {//arObj.setAge(arObj.getAge() + 1);ar.getAndSet(new ARObj("张三", ai.incrementAndGet()));}countDownLatch.countDown();});}countDownLatch.await();//System.out.println(arObj.getAge());System.out.println(ar.get().getAge());}
}@Data
@AllArgsConstructor
class ARObj {private String name;private int age;
}

AtomicMarkableReference

属性:Unsafe、Object、boolean

同时保证对一个对象和一个boolean类型的标识符的原子操作(在CAS操作时,同时判断对象跟boolean的原值是否与之前一致,都一直才会对对象和boolean更新,否则不更新)

// 缓存,reference为缓存对象,mark为缓存生效标识
public class AtomicMarkableReferenceDemo {public static void main(String[] args) {Map<String, Object> map = new HashMap<>();map.put("name", "李四");map.put("age", 20);AMRCache amrCache = new AMRCache(map);System.out.println(amrCache.get("name"));amrCache.invalidCache();System.out.println(amrCache.get("name"));}
}class AMRCache {AtomicMarkableReference<Map<String, Object>> amr = new AtomicMarkableReference<>(null, true);public AMRCache(Map<String, Object> cache) {amr.set(cache, true);}public Object get(String key) {boolean[] markHolder = new boolean[1];Map<String, Object> expectedReference = amr.get(markHolder);boolean expectMark = markHolder[0];if (expectMark) {return expectedReference.get(key);}Map<String, Object> newReference = new HashMap<>();newReference.put("name", "张三");newReference.put("age", 18);boolean newMark = true;do {expectedReference = amr.get(markHolder);expectMark = markHolder[0];} while (!amr.compareAndSet(expectedReference, newReference, expectMark, newMark));return newReference.get(key);}// 使缓存失效(更新boolean=false)public void invalidCache() {boolean[] markHolder = new boolean[1];Map<String, Object> expectedReference = null;do {expectedReference = amr.get(markHolder);} while (!amr.attemptMark(expectedReference, false));}}

AtomicStampedReference

同时保证对一个对象和一个int类型的标识符的原子操作(在CAS操作时,同时判断对象跟int的原值是否与之前一致,都一直才会对对象和int更新,否则不更新)

// ABA问题
public class AtomicStampedReferenceDemo {public static void main(String[] args) {AtomicStampedReference<String> asr = new AtomicStampedReference("张三", 0);int[] stampHolder = new int[1];String expectedReference = null;String newReference = "李四";int expectedStamp;int newStamp;do {expectedReference = asr.get(stampHolder);expectedStamp = stampHolder[0];newStamp = expectedStamp + 1;} while (!asr.compareAndSet(expectedReference, newReference, expectedStamp, newStamp));}
}

ReentrantLock

属性:Sync(Sync继承AQS(AbstractQueuedSynchronizer)类)
AQS中含有属性:state、exclusiveOwnerThread,head、tail。
state代表锁的状态,0表示锁未被使用,1代表被使用且未被重入,2代表被某个线程使用且重入一次。
exclusiveOwnerThread表示持有当前锁的线程。
node节点含有属性:prev、next、thread对象、waitStatus。首次初始化时,head=tail=new Node()

lock()

1、尝试获取
如果state==0,尝试通过unsafe.CAS将state从0替换成1,如果成功,更新exclusiveOwnerThread=当前线程,逻辑结束;
如果state>0,判断持有锁的线程是否是当前线程,是的话,state++,逻辑结束。

2、加入队列
如果上一步获取失败,将该线程创建的node加入到等待队列尾部。CAS循环,不断尝试将创建的node赋值给tail,且node.prev=原tail,原tail.next=node

3、线程阻塞
for循环,如果prev.waitStatus>0,移除;如果prev.waitStatus=0,CAS尝试将prev.waitStatus从0替换成-1(-1代表当前节点释放锁之后,立即唤醒下一个节点的线程)如果替换成功,通过LockSupport.park()阻塞当前线程。

4、等待唤醒
for循环,判断prev是否是head,如果是,走第一步的逻辑尝试获取锁,获取失败走第三步的逻辑线程阻塞。

tryLock()

跟reentrantLock.lock()原理相识,只是如果在第三步与第四步过程中超时,会将node.waitStatus=1,后续节点判断该node.waitStatus>0,就会移除掉该节点。

unlock()

1、判断持有锁的线程是不是当前线程,不是的话抛异常,是的话state–

2、如果state减完之后等于0,持有锁的线程=null,判断head是否等于null,如果不等于说明等待队列有数据,再判断head.waitStatus是否!=0,不等于的话,就会通过LockSupport.unpark()唤醒下一个waitStatus≤0的节点。

Condition

// 等待通知机制(交替打印)
public class ConditionDemo {static AtomicInteger ai = new AtomicInteger(0);public static void main(String[] args) {ReentrantLock reentrantLock = new ReentrantLock();Condition condition = reentrantLock.newCondition();new Thread(() -> {while (ai.get() < 100) {reentrantLock.lock();try {while (ai.get() % 2 == 0) {try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("奇 =>" + ai.getAndIncrement());condition.signal();} finally {reentrantLock.unlock();}}}).start();new Thread(() -> {while (ai.get() < 100) {reentrantLock.lock();try {while (ai.get() % 2 == 1) {try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("偶 =>" + ai.getAndIncrement());condition.signal();} finally {reentrantLock.unlock();}}}).start();}
}

ReentrantReadWriteLock

用于优化读多写少场景下的性能。

写锁没被使用时,读锁可以同时被多次使用。

写锁被使用时,其他读锁和写锁都要阻塞。

存在问题:读锁不断被使用,导致写锁一直阻塞。

属性:Sync(Sync继承AQS(AbstractQueuedSynchronizer)类)

其中state的前16位表示拥有读锁的线程个数,后16位表示某个写锁的重入次数。

writeLock.lock();

1、尝试获取(与ReentrantLock略有不同)
如果state==0,尝试通过unsafe.CAS将state从0替换成1,如果成功,更新exclusiveOwnerThread=当前线程,逻辑结束;
如果state>0,此时如果后16位不等于0且持有锁的线程等于当前线程,说明要重入,state++,逻辑结束;如果后16位等于0说明此时读锁被持有,并且持有读锁的线程不等于当前线程,此时获取锁失败。

2、加入队列
如果上一步获取失败,将该线程创建的node加入到等待队列尾部。CAS循环,不断尝试将创建的node赋值给tail,且node.prev=原tail,原tail.next=node

3、线程阻塞
for循环,如果prev.waitStatus>0,移除;如果prev.waitStatus=0,CAS尝试将prev.waitStatus从0替换成-1(-1代表当前节点释放锁之后,立即唤醒下一个节点的线程)如果替换成功,通过LockSupport.park()阻塞当前线程。

4、等待唤醒
for循环,判断prev是否是head,如果是,走第一步的逻辑尝试获取锁,获取失败走第三步的逻辑线程阻塞。

writeLock.unlock();

1、判断持有锁的线程是不是当前线程,不是的话抛异常,是的话state–

2、如果state减完之后后16位等于0(与ReentrantLock略有不同),说明当前写锁未被任何线程持有,设置持有锁的线程=null,判断head是否等于null,如果不等于说明等待队列有数据,再判断head.waitStatus是否!=0,不等于的话,就会通过LockSupport.unpark()唤醒下一个waitStatus≤0的节点。

readLock.lock()

1、尝试获取(与ReentrantLock略有不同)
判断state的后16位是否不等于0,不等于0说明写锁被占用,此时再判断持有锁的线程是否等于当前线程,如果不等于,获取锁失败;
其他情况下,state的前16位++,该线程的threadlocal对象的count++。

2、加入队列
如果上一步获取失败,将该线程创建的node加入到等待队列尾部。CAS循环,不断尝试将创建的node赋值给tail,且node.prev=原tail,原tail.next=node

3、线程阻塞
for循环,如果prev.waitStatus>0,移除;如果prev.waitStatus=0,CAS尝试将prev.waitStatus从0替换成-1(-1代表当前节点释放锁之后,立即唤醒下一个节点的线程)如果替换成功,通过LockSupport.park()阻塞当前线程。

4、等待唤醒
for循环,判断prev是否是head,如果是,走第一步的逻辑尝试获取锁,获取失败走第三步的逻辑线程阻塞。

readLock.unlock()

1、该线程的threadlocal对象的count–

2、CAS循环尝试将state前16位–,成功后如果前16位=0,唤醒等待队列的下一节点。

// 缓存
public class ReentrantReadWriteLockDemo {public static void main(String[] args) {RRWLCache.put("name", "张三");RRWLCache.get("name"); // 张三}
}class RRWLCache {private static ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();private static ReentrantReadWriteLock.ReadLock readLock = rrwl.readLock();private static ReentrantReadWriteLock.WriteLock writeLock = rrwl.writeLock();private static Map<String, Object> cache = new HashMap<>();public static Object get(String key) {readLock.lock();try {return cache.get(key);} finally {readLock.unlock();}}public static void put(String key, Object value) {writeLock.lock();try {cache.put(key, value);} finally {writeLock.lock();}}
}

StampedLock

读写锁,与ReentrantReadWriteLock的区别是提供一种新的读锁:乐观读锁。
获取乐观读锁的操作并不会阻塞其他线程获取读锁,但是我们要校验读锁的有效性,即中间是否有其他线程获取了写锁,如果有,再尝试获取读锁。

public class MyTest {static int num = 0;static StampedLock sl = new StampedLock();public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);CountDownLatch countDownLatch = new CountDownLatch(3);threadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}long stamp = sl.tryOptimisticRead();if (!sl.validate(stamp)) {stamp = sl.readLock();try {System.out.println(stamp + "悲观线程1===>" + num);} finally {sl.unlockRead(stamp);}} else {System.out.println(stamp + "线程1===>" + num);}countDownLatch.countDown();/*long stamp = sl.readLock();try {TimeUnit.SECONDS.sleep(4);System.out.println(stamp + "线程1===>" + num);} catch (InterruptedException e) {e.printStackTrace();} finally {sl.unlockRead(stamp);}countDownLatch.countDown();*/});threadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(4);} catch (InterruptedException e) {e.printStackTrace();}long stamp = sl.tryOptimisticRead();if (!sl.validate(stamp)) {stamp = sl.readLock();try {System.out.println(stamp + "悲观线程2===>" + num);} finally {sl.unlockRead(stamp);}} else {System.out.println(stamp + "线程2===>" + num);}countDownLatch.countDown();});threadPool.execute(() -> {/*try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}*/long stamp = sl.writeLock();try {TimeUnit.SECONDS.sleep(2);num++;} catch (InterruptedException e) {e.printStackTrace();} finally {sl.unlockWrite(stamp);}countDownLatch.countDown();});countDownLatch.await();System.out.println(num);}
}

ArrayBlockingQueue

基于数组实现的有界阻塞队列。

CompletableFuture

四种创建方式:

ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture.runAsync(() -> {});
CompletableFuture.runAsync(() -> {}, threadPool);
CompletableFuture.supplyAsync(() -> null);
CompletableFuture.supplyAsync(() -> null, threadPool);

1、阻塞主线程,获取结果

ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}return new Random().nextInt(10);
}, threadPool);
Integer join = completableFuture.join(); // 阻塞当前线程

2、任务串行执行
不能先创建CompletableFuture对象,在调用completableFuture.handle() 这样会导致join()先于handle()执行。
方式一:获取上一步的返回结果和异常信息

ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一步返回结果:" + 1);return 1;
}, threadPool).handle((result, exception) -> {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}if (exception == null) {System.out.println("上一步结果:" + result);} else {System.out.println("上一步异常:");exception.printStackTrace();}return 2;
});

方式二:thenRun()方法异步执行,不影响join()返回结果,所以先执行了join()

ExecutorService threadPool = Executors.newFixedThreadPool(5);
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第一步返回结果:" + 1);return 1;
}, threadPool);
completableFuture.thenRun(() -> {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("第二步以触发");
});
System.out.println(completableFuture.join());
}

3、任务间的交互

public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);CompletableFuture<Integer> f1 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("返回1");return 1;}, threadPool);CompletableFuture<Integer> f2 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("返回3");return 3;}, threadPool);System.out.println(f1.thenCombine(f2, (r1, r2) -> {System.out.println("r1=" + r1);System.out.println("r2=" + r2);return r1 + r2;}).join());
}

ConcurrentHashMap

多线程环境下可以保证线程安全的map容器。

ConcurrentLinkedDeque

TODO:JRB

ConcurrentLinkedQueue

TODO:JRB

ConcurrentSkipListMap

TODO:JRB

ConcurrentSkipListSet

TODO:JRB

CopyOnWriteArrayList

TODO:JRB

CopyOnWriteArraySet

TODO:JRB

CountDownLatch

通过await()阻塞当前线程执行,直到指定次数的countDown()执行完

CyclicBarrier

cyclicBarrier.await()时,直有该cyclicBarrier的所有的await()都触发时,才会往下执行。
可以用多次。

public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);CyclicBarrier cyclicBarrier = new CyclicBarrier(3, () -> {System.out.println("3个await()执行完就触发");});threadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(1);System.out.println("线程一完成1阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(2);System.out.println("线程一完成2阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(3);System.out.println("线程一完成3阶段");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});threadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(2);System.out.println("线程二完成1阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(1);System.out.println("线程二完成2阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(2);System.out.println("线程二完成3阶段");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});threadPool.execute(() -> {try {TimeUnit.SECONDS.sleep(3);System.out.println("线程三完成1阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(2);System.out.println("线程三完成2阶段");cyclicBarrier.await();TimeUnit.SECONDS.sleep(1);System.out.println("线程三完成3阶段");} catch (InterruptedException | BrokenBarrierException e) {e.printStackTrace();}});
}

输出结果:
线程一完成1阶段
线程二完成1阶段
线程三完成1阶段
3个await()执行完就触发
线程二完成2阶段
线程一完成2阶段
线程三完成2阶段
3个await()执行完就触发
线程三完成3阶段
线程二完成3阶段
线程一完成3阶段

DelayQueue

TODO:JRB

Exchanger

用于两个线程之间交换数据。

public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);Exchanger<Integer> exchanger = new Exchanger<>();threadPool.execute(() -> {int result = 0;for (int i = 0; i < 5; i++) {result += i;}Integer sum = Integer.valueOf(result);try {TimeUnit.SECONDS.sleep(3);Integer exchange = exchanger.exchange(sum);System.out.println("线程一收到结果:" + exchange);System.out.println("总和=" + sum + exchange);} catch (InterruptedException e) {e.printStackTrace();}});threadPool.execute(() -> {int result = 0;for (int i = 0; i < 5; i++) {result += i;}Integer sum = Integer.valueOf(result);try {TimeUnit.SECONDS.sleep(1);// 阻塞,知道另一个exchanger.exchange()执行Integer exchange = exchanger.exchange(sum);// 非阻塞,超时会报TimeoutException//Integer exchange = exchanger.exchange(sum, 1, TimeUnit.SECONDS);System.out.println("线程二收到结果:" + exchange);System.out.println("总和=" + sum + exchange);} catch (InterruptedException e) {e.printStackTrace();}});
}

ExecutorCompletionService

TODO:JRB

Executors

TODO:JRB

ForkJoinPool

将一个复杂的大任务递归拆分为多个小任务(fork),直到子任务足够小可以直接处理;然后合并所有子任务的结果(join),得到最终结果。例如:计算 1~1000000 的和,可拆分为 1100000、100001200000 等子任务,分别计算后汇总。

Thread

new Thread().interrupt();
作用:设置目前线程的中断标志为true,此时若目标线程处于阻塞状态(如 sleep()/wait()),会立即抛出 InterruptedException并清除中断标志。

new Thread().isInterrupted();
作用:仅查询目前线程的中断标志

Thread.interrupted();
作用:查询当前线程的中断标志,并重置(重置为false)

java.util

ThreadLocal

public class ThreadLocalDemo {static ThreadLocal<Integer> threadLocal = new ThreadLocal<>();public static void main(String[] args) {ExecutorService threadPool = Executors.newFixedThreadPool(5);for (int i = 1; i < 6; i++) {final int value = i;threadPool.execute(() -> {threadLocal.set(value);threadLocal.get(); // 1threadLocal.remove();threadLocal.get(); // null});}}
}

set(value)

thread对象有一个属性:ThreadLocal.ThreadLocalMap,

ThreadLocalMap中有一个Entry类型的数组,Entry属性包括当前threadLocal对象,以及value值,索引根据threadLocal对象的哈希值对数组长度取余算得。

第一步:取出当前线程的threadLocalMap属性,如果为空直接new一个新的threadLocalMap

第二步:将当前threadLocal对象以及value封装成Entry,根据当前threadLocal算出索引,赋值给threadLocalMap.entry[ ]中。

get()

第一步:取出当前线程的threadLocalMap属性

第二步:根据当前threadLocal对象算出索引,取出threadLocalMap.entry[ ]的该索引entry,如果不为null,返回entry.value

remove()

第一步:取出当前线程的threadLocalMap属性

第二步:根据当前threadLocal对象算出索引,设置threadLocalMap.entry[索引值]=null

http://www.dtcms.com/a/480687.html

相关文章:

  • 专业外贸网站制作价格网站推广的渠道有
  • 网站建设及管理制度中国十大电商培训机构
  • 旅游网站建设报价单东营两学一做网站
  • 铁岭网络推广网站建设桂林网站优化注意事项
  • 惠城中山网站建设wordpress头像显示空白
  • 企业官网建站费用本地门户网怎么做
  • 做素材网站赚钱吗高端网站建设 上海
  • 怎么组建企业网站wordpress 连载
  • 建设商城购物网站wordpress自定义分页
  • 最专业的微网站开发微信如何建商城网站
  • 网站图片自动轮换怎么做的做任务挣钱的网站聚
  • 帮助网站网站做优化设计网站下载
  • 360网站推广官网球阀秦皇岛北戴河
  • 福州市网站电商网站营销
  • 四川企业网站建设seo实战密码第四版电子书
  • 天津市建设教育培训中心网站免费咨询造成损害
  • 网站seo入门东莞网站设计百年
  • 中山网站建设文化咨询广告推广的软件
  • 珠宝 网站欣赏个体户营业执照科研做企业网站吗
  • 做网站销售药品wordpress弹幕播放器插件
  • 网上的彩票网站是怎么做的电商运营主要工作内容
  • 基于jsp网站开发开题报告制作网站的走马灯怎么做
  • 城乡与建设部网站首页编程项目实例网站
  • 哪个网站查备案价莱芜在线论坛话题莱芜都市网
  • 做绿色产品的网站企业营销策划合同范本
  • 男生浏览器推荐安徽关键词seo
  • 怎样加入好大夫网站做医生深圳市手机网站建设哪家好
  • 网站开发过程模型google adsense wordpress 插件
  • 电子商务网站的全面建设品牌建设规划方案
  • 湘潭网站建设公司有哪些用手机怎么打开电脑版的智慧团建