Solo  当前访客:2 开始使用

CoderV的进阶笔记


Everybody wants go to heaven, but nobody wants to die.

同步容器和并发容器总结 有更新!

2019-09-21 15:21:26 valarchie
0  评论    0  浏览

什么是同步容器?

同步容器通过synchronized关键字修饰容器保证同一时刻内只有一个线程在使用容器,从而使得容器线程安全。synchronized的意思是同步,它体现在将多线程变为串行等待执行。(但注意一点,复合操作不能保证线程安全。举例:A线程第一步获取尾节点,第二步将尾结点的值加1,但在A线程执行完第一步的时候,B线程删除了尾节点,在A线程执行第二步的时候就会报空指针)

什么是并发容器?

并发容器指的是允许多线程同时使用容器,并且保证线程安全。而为了达到尽可能提高并发,Java并发工具包中采用了多种优化方式来提高并发容器的执行效率,核心的就是:锁、CAS(无锁)、COW(读写分离)、分段锁。

生产者消费者模式的四种实现方式 有更新!

2019-09-20 09:17:35 valarchie
0  评论    0  浏览

简述

生产者消费者模式简而言之就是两种不同的线程分别扮演生产者和消费者,通过一个商品容器来生产商品和消费商品。生产者和消费者模式是学习多线程的好例子,下文就以四种不同实现的消费者生产者模式来理解多线程的编程。

以下的例子都共用消费者和生产者对象,而将商品容器(Stock)按照四种形式进行实现。

生产者:

生产者持有商品容器,并实现了Runnable接口,在run方法中无限循环地往商品容器stock中放入商品。

public class Producer implements Runnable{
    // 商品容器
    private Stock stock;

    public Producer(Stock stock) {
        this.stock = stock;
    }

    @Override
    public void run() {

        while (true) {
            // 随机生成商品 放入商品容器 stock中
            String product = "商品" + System.currentTimeMillis() % 100;
            System.out.println("生产了" + product);
            stock.put(product);
            // 休眠0.5秒 
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

    }
}

FixedThreadPool vs CachedThreadPool

2019-09-17 00:17:33 valarchie
0  评论    0  浏览

之前写了一篇文章关于四种线程池的解析。
但是对于FixedThreadPool与CachedThreadPool适用的场景其实还是比较模糊难以界定的。所以笔者今天通过设计大任务并发和小任务并发来验证FixedThreadPool与CachedThreadPool的适用场景。

首先我设计了一个任务基类,它通过计算圆周率来模拟cpu的密集计算、通过写日志到本地文件来模拟IO。
这两个方法都通过参数n来调整任务的大小规模。

四种线程池的解析

2019-09-13 02:33:41 valarchie
0  评论    0  浏览

首先我们先看一下获取四种线程池的代码:

    ExecutorService fixedThreadPool = Executors.newFixedThreadPool(10);
    ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    ExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(10);
    ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();

可以发现这四种线程池都是由Executors类生成的。依次点开四个方法的内部实现发现,它们最终调用的都是同一个ThreadPoolExecutor()的构造器,而区别在于构造器的参数不同。我们来看下ThreadPoolExecutor的参数列表:

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {

正是由于这几个参数的不同导致了四种线程池的工作机制不同。参考源码对于参数的注释,我们列出参数的含义。

负载均衡的多种算法总结 有更新!

2019-09-12 00:18:30 valarchie
0  评论    0  浏览

随机算法

先将服务器放进数组或者列表当中,通过JDK的随机算法,获取一个在数组有效范围内的下标,根据这个随机下标访问对应服务器。由概率统计理论可以得知,随着客户端调用服务器的次数增多,其实际效果越来越接近于平均分配请求到服务器列表中的每一台服务器。

代码:

 public String random(){
        String[] servers = {"server1", "server2", "server3"};
        // 将系统的当前时间作为种子获取一个随机器
        Random generator = new Random(System.currentTimeMillis());
        // 将服务器列表大小作为上界传入随机生成器
        int index = generator.nextInt(servers.length);
        return servers[index];
    }

为什么要使用SpringIOC? 有更新!

2019-09-11 15:57:49 valarchie
0  评论    0  浏览

思考

Spring已经占据我们Java开发框架中的半壁江山了,从一开始工作我们就在使用Spring。但是到底为什么要用Spring,可能很多人都没有去思考过这个问题?许多人可能也疲于应对需求,无暇思考这种看似理所当然的问题。那今天,我们就好好来讨论一下究竟为什么要使用Spring IOC?

逆向思考

假设在最初没有Spring IOC这种框架的时候,我们采用传统MVC的方式来开发一段常见的用户逻辑。

用户DAO

public class UserDAO {

    private String database;

    public UserDAO(String dataBase) {
        this.database = dataBase;
    }
    public void doSomething() {
        System.out.println("保存用户!");
    }

}

用户Service

public class UserService {

    private UserDAO dao;

    public UserService(UserDAO dao) {
        this.dao = dao;
    }
    public void doSomething() {
        dao.doSomething();
    }

}

用户Controller

public class Controller {

    public UserService service;

    public Controller(UserService userService) {
        this.service = userService;
    }

    public void doSomething() {
        service.doSomething();
    }

}

Spring IOC过程源码解析 有更新!

2019-09-10 18:41:40 valarchie
0  评论    0  浏览

废话不多说,我们先做一个傻瓜版的IOC demo作为例子

自定义的Bean定义

class MyBeanDefinition{

    public String id;
    public String className;
    public String value;

    public MyBeanDefinition(String id, String className, String value) {
        this.id = id;
        this.className = className;
        this.value = value;
    }

}

GOF设计模式小白教程之适配器模式 有更新!

2019-09-04 12:25:29 valarchie
0  评论    0  浏览

适配器模式(Adapter)

定义:

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

通俗解释:

有一个中国人和一个日本人,他们都只会母语并且不想再学习其他语言(意味着不修改两个不兼容的类的代码)。但是他们之间又想进行交流,那怎么办呢?这时候如果有翻译的话就可以让中国人和日本人不用学习新的语言,即可互相交流。这里的中国人和日本人是互不兼容的两个接口,而翻译就是他们之间的适配器。

GOF设计模式小白教程之原型模式 有更新!

2019-09-03 23:59:12 valarchie
0  评论    0  浏览

原型模式(Prototype)

定义:

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。

通俗解释:

美术课上老师布置了一个素描作业。然后同学们让美术课代表画了素描作业。其他同学就可以拿着这份素描作业去复印店复印。其他同学完全不用知道怎么画这个素描。美术课代表画的素描作业就是已经创建实例。它作为原型。用这个原型复制出新素描的话,无需关心素描细节。

GOF设计模式小白教程之建造者模式 有更新!

2019-09-03 23:57:33 valarchie
0  评论    0  浏览

建造者模式(Builder)

定义:

将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。

通俗解释:

有一个包工头负责建房子。房子主要由地基,墙,屋顶构成。他设计了建房的图纸(先打地基,再砌墙,再盖屋顶)。包工头手下有工人,工人分为石材工和木头工。工人都会打造地基、墙还有屋顶。包工头想盖木房子的话,就把木材工叫过来,把建房的图纸给他。同理,想盖石头房子的话,就把石材工叫来,还是用原来那份建房的图纸给他(意味着不用修改代码即可建不同的房子)。

TOP