Java并发(三)

by:leotse

返回值

我们知道,可以通过创建Runnable来创建任务,但是我们却不能通过这种方式返回值。Java因此提供了另一个接口来达到返回一个值的目的,这个接口就是Callable。Callable是一种具有类型参数的泛型,它的类型参数表示的是从call()方法中返回的值的类型,我们通过ExecutorService.submit()来调用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.leotse.thread;

import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class CallableTask implements Callable<String>{

private int id;
public CallableTask(int id) {
this.id = id;
}

@Override
public String call() throws Exception {
return "This is task " + id;
}

public static void main(String[] args) {
ExecutorService eService = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<Future<String>>();
for (int i=0; i<5; i ++){
results.add(eService.submit(new CallableTask(i)));
}

for (Future<String> r : results){
try {
System.out.println(r.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
eService.shutdown();
}
}
}

}

Java并发(二)

by:leotse

Java的线程机制

我们在上一篇博客中,提到最理想的实现并发编程的方式就是使用进程,但是Java中我们使用线程进行多任务处理,原因在上一篇博客中也已经提及。

在Java中,每一个线程都会对应一个任务,这些任务构成了一个并发的程序。 在底层看来,每一个线程都觉得自己独占了CPU,虽然事实上它们只是在某一个时间切片上占有了CPU。CPU会轮流给每一个线程分配时间,这些细节一般不需要我们去了解。

Runnable接口

我们知道,Java中的并发程序是由任务构成,那么Java中怎么声明一个任务呢?Java为我们提供了一个Runnable接口,凡是实现了Runnable接口的类皆可以称之为一个任务。下面的实例展示了Java中如何声明任务:

1
2
3
4
5
6
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("I am a task");
}
}

Java并发(一)

by:leotse

并发,并发,并发

有顺序编程,就有并发编程。事实上,几乎我们所有的程序都可以通过顺序编程来完成,只是你必须忍受一些非常情况。
并发说起来很奇怪,它具有可论证的确定性,但是实际上却具有不可确定性。它的不可确定性是因为你没有办法预知在实际情况下会发生事情导致工作失败,而且你也没有办法通过编写代码进行完备的测试。
虽然实际应用中,并发很难做到完全掌握,但是这不能成为我们不作为的理由。

如果视而不见,你就会遭其反噬。

作为一名骄傲的程序员,并发编程是基础,也是必备知识。

为什么需要并发

这是一个老生常谈的问题,但是我们不能规避这个问题,要想深入理解一件事物,就必须弄清楚它的来龙去脉。

企业计算的终结

作者:尼古拉斯·卡尔
翻译:黄思路
文章来源:《斯隆管理评论》

这是在36kr上看到的一篇文章,对于文中有关信息技术发展的理解感触颇深,于是kiang到了这里(原文)。

花费数百万美元打造内部数据中心后,企业往往会发现面临着快速淘汰这些数据库的窘境。IT 正从一种企业资产转变为一种服务购买。

20 世纪早期,有一些之前的几十年里无法想象的事情陆续发生:制造厂商开始关闭、拆除水轮设备、蒸汽机和发电机。要知道,从工业时代开始,电力就是任何产业得以运作的必要前提,工厂作坊除了维持独立发电站来使运作机器以外别无选择。新世纪的到来带来了一种新的可能,许多新兴发电商开始通过建立中央电厂和使用电网给远距离外的客户输送电能。制造商本身不需要再维持独立发电站的运营,他们可以从这些新兴发电商那里购买需要的用电。

几乎过了整整一个世纪后,历史再次重演。过去50年中最重要的一项商业成就——信息技术——正在经历类似的转变。信息技术曾以电脑、软件和其他各式各样的形式作为公司的一种资产,而现在,它正在转化为一种从效用供应商那里购买的服务。商业界很少有公司真正意识到这个转变的重大意义和深远影响。至今,关于效应计算的讨论也仅仅是停留在信息技术供应商的市场标语里,如同那些含义模糊的各类名词,“自动系统”、“服务及虚拟化”、“服务型架构” 等等。其实这些充满官腔的言词不仅没有着向大众照亮这一转变的未来,更使人们对于它的理解变得非常模糊。

ES之当你更新Document,你在更新些什么?

by:leotse

怎么更新ElasticSearch中的Document?

在ES中更新数据的场景有很多,比如我们要修改一个用户的年龄、爱好,又或者我们需要实时同步MySQL中的数据到ES中。我们都有修改已经存在的Document的需求。ES本身提供了两种方法让我们修改一个Document的数据,我们假设我们想要修改的内容如下:

1
2
3
4
5
6
GET /test/customer/1/_source

{
"name": "yolovon",
"age": 24
}

我们想将yolovon女神的年龄修改到真实年龄18岁。我们可以进行以下两种方法:
1.使用PUT,就像我们插入数据时那样:

1
2
3
4
5
6
7
8
9
10
11
12
13
PUT /test/customer/1
{
"name": "yolovon",
"age": 18
}

{
"_index": "test",
"_type": "customer",
"_id": "1",
"_version": 2,
"created": false
}

ElasticSearch与MySQL数据同步

by:leotse

ES与MySQL的数据同步

如果你需要进行ES与MySQL的数据同步,亦即将MySQL中的数据导入到ES中,并保持同步,一般来看,有以下几种方法:
1.自己动手写一个同步的模块。实时tail处理MySQL的binlog,将数据库的新增、修改或删除这些操作同步在ES上执行。这种方案可行,但是实现起来代价大;

2.go-mysql-elasticsearch。这是Git上的一个开源项目,差不多是第一种方案的一个实现版本。这个插件支持实时同步MySQL与ES的新增、修改以及删除操作。但是缺点是使用起来不够灵活,它的作者给出了它的以下缺点:

-binlog row image must be full for MySQL, you may lost some field data if you update PK data in MySQL with minimal or noblob binlog row image. MariaDB only supports full row image.
-Can not alter table format at runtime.
-mysqldump must exist in the same node with go-mysql-elasticsearch, if not, go-mysql-elasticsearch will try to sync binlog only.