`
文章列表
首先说明的是,这个和 ReadWriteLock 一样,同样是使用一个状态,包含两部分含义,一部分是线程池的运行状态,一个是线程池中的 Worker 数量. corePoolSize: 核心线程的数量. maximumPoolSize: 线程池中允许的最大线程数. keepAliveTime: 空闲线程等待的时间,超过这个时间,则销毁. largestPoolSize: 跟踪线程池中的最大线程数 allowCoreThreadTimeOut: 是否允许核心线程超时,若允许核心线程超时,那么 keepAliveTime 同样对核心线程有效. 当线程池执行 execute 方法时: 1 ...
Java 并发中会大量使用到多线程,那么Java是如何使用多线程执行任务了? 线程池. 那线程池是如何调度任务的了? 按照我的理解是,Java 对 Runnable 或者 Callable 进行封装,Runnable 首先会被封装成 Callable, 然后对 Callable 做进一步的封装,封装成 FutureTask. 然后线程池调度 FutureTask, 但是实际上的执行还是通过 Runnable 或者 Callable 的 run 方法进行执行的.

Java Void 类型

    博客分类:
  • JAVA
今天看源码的时候发现了 Void 这个类型(不是 void) void 表示没有返回值,而 Void 表示返回 null.
public interface BlockingQueue<E> extends Queue<E> {     /**      * 插入指定元素到队列中,如果没有超出容量限制的话, 插入成功,返回 true. 如果没有空间的话,抛出 IllegalStateException.      * 当使用有容量限制的队列(queue)时,通常最好是使用 offer(Object) 方法.      *      */     boolean add(E e);     /**      * 插入指定元素到队列中,如果没有超出容量限制的话, 插入成功,返回 true, 如果 ...
LinkedBlockingQueue 其实实现的是一个生产者消费者模式. 同一时刻,一个线程可以向队列中放东西,另一个时刻可以从队列中拿东西走. 如何实现多线程安全了? LinkedBlockingQueue 采用了 ReentrantLock 作为并发控制. 还有就是对 count 进行原子操作.
waiter 存放等待的线程,这是一个单链表,没有用 lock 或者 sync 但是实现了线程安全. static final class WaitNode {         // 记录当前线程.         volatile Thread thread;         // 指向下一个线程.         volatile WaitNode next;         WaitNode() { thread = Thread.currentThread(); }     } 这里为啥会使用 volatile 进行修饰了,而 Treober Stack 中则没有使用 volatil ...
boolean cancel(boolean mayInterruptIfRunning) 方法描述: /**      * Attempts to cancel execution of this task.  This attempt will      * fail if the task has already completed, has already been cancelled,      * or could not be cancelled for some other reason. If successful,      * and this task has not ...

JAVA注解

    博客分类:
  • JAVA
5个基本的 Annotation 如下: @Override:指定方法重写 @Deprecation:标记已过时 @SuppressWarnings:抑制编译期警告,例如:@SuppressWarnings(value=“unchecked") @SafeVarargs @FunctionalInterface 自定义注解 Public @interface Test{ } 使用 @Test public class MyClass{ } 注解是一种标记,为一个类打上标记后,以后就可以通过反射来获取注解以及注解上的值,用于其他操作. 例如:Spring 中的 @Serv ...
对于传统的服务:我们是知道它提供服务的地址(ip + port). 这时候,我们能够进行很方便的调用. 但是对于微服务就不同了,服务是动态分配的地址,所以无法像调用传统服务那样进行调用. 如何解决了? 习惯性的想法,我们可以找个代理(负载均衡器)呀,让它帮我们去查,查完后,调用服务.这种方式称为服务端发现. 还有一种想法就是,找代理多麻烦,我自己干(自己查),查完后,调用服务.这种方式称为客户端发现. 客户端发现方法中客户端和服务注册表之间存在很严重的耦合,导致每一个客户端都得写一套发现逻辑. 服务端发现就能避免这个问题.
首先说下为啥会有限流: 比如说:双11,全民购物狂欢节,虽然我们买东西可开心了,但是会有一个问题. 比如说淘宝服务本来只能支持 10 个人同时访问,但是在有 10000 个人同时访问了,这就会导致系统资源耗尽,最终服务崩掉. 限流的目的是为了控制访问的流量. 比如说它支持10人访问,那么我就控制每次只有10个人访问. 限流的策略: 1.令牌桶: 首先这个桶是有容量的,比如说10.然后每秒钟向桶中放 x 个令牌,当放入的令牌总数 > 桶的容量时,则溢出.(拒绝服务). 每次请求来了,需要先去桶中获取一个令牌才能执行(消费令牌).这样就能控制访问的数量了. 可以理解为生产者-消费者模 ...
在互联网项目中,会大量的用到缓存,例如: 192.168.0.10/192.168.0.11/192.168.0.12 三台机器上都有缓存. 现在用户A 要查询 key 对应的 value 放在那台机器上,那应该怎么处理了? 一般的思路是通过模运算来解决,例如:用 x % N 的结果去对应的机器上去查找. 比如:1 = x % N, 那么就去 192.168.0.10 这台机器上查找. 但是这有一个问题,当一个机器宕机的时候,或者随着访问量的增大,需要新增加机器,那么这时候,通过模运算将会存在大量的不命中. 因为不管是宕机或者新增加机器,都会涉及到 N 的变化,就会导致和以前存储时获得的 ...
/* * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package com.hanlin.fadp; import java.lang.ref.*; /** * This class extends <tt&g ...
说明: 每个线程内部持有一个 ThreadLocalMap 的东西,而我发现 ThreadLocal 内中 nextHashCode 为静态变量,这就意味着该变量为所有 ThreadLocal 锁共有. 现在考虑一种极端情况,有两个 ThreadLocal 实例:ThreadLocalA 和 ThreadLocalB. 两个线程:ThreadA 和 ThreadB. ThreadLocalA 存有线程A和线程B的数据. 反应到底层的数据结构是: ThreadA.ThreadLocalMap<ThreadLocalA, Value> ThreadB.ThreadLocalMap ...
1.首先说明 ReentrantReadWriteLock 和 IO操作没有关系,只是说将读操作和写操作分开,提高性能 2.实现原理: 用 state 的高 16 位表示读锁的数量,用 state 的低 16位表示写锁的数量 可以申请到写锁的条件: 1.没有线程持有锁(读锁和写锁,锁是不能升级的,比如说当前线程持有读锁,但是后面该线程申请不到写锁) 2.当前线程持有写锁(这种情况时说,本线程已经持有锁了,换句话说,WriteLock 是可重入锁) 可以申请到读锁的条件: 1.没有线程持有锁 2.当前线程持有写锁
思路分析: CountDownLatch 的思路是:首先申请锁的时候,假设以 6 申请锁. 此时线程阻塞. 参考独占锁中的重入锁. 此时:假设一个独占锁多次申请锁的话,那么假设此时 state = 6. 这时候就跟共享锁初始的时候申请锁差不多了. 现在每调用一次 countDown 方法的时候,state -1 当 state = 0 的时候,是不是说明没有再占用锁了?那么此时线程就可以执行了. CountDownLatch 的实现思路从始至终只有一个线程在队列中,也就是主线程. 它的 countDown 方法只是将 state 减一. 当 count=0时,调用 doRe ...
Global site tag (gtag.js) - Google Analytics