数据存储、TOS 、Java并发 | 青训营笔记

59 阅读2分钟

LSMT存储引擎


传统数据库:

  • 计算层:SQL解析、查询优化、计划执行
  • 存储层:
    • AICD
    • 屏蔽IO

数据库id增长方案: - UUID - AUTO-ID - redis的incr,考虑持久化 - 雪花算法

  • 子结构
    • SSTabke(Stored String Table),KV结构顺序排列的文件——不可修改
    • MemTable:于内存中的数据结构
    • log文件

LSMT和B+Tree

  • 顺序写模型对于 SSD 设备更友好
  • SST 不可修改的特性使得其能使用更加紧凑的数据排列和加上压缩
  • 后台延迟 Compact 能更好利用 CPU 多核处理能力,降低前台请求延迟

Hbase

  • 其直接存储在HDFS

RocksDB

  • 批量WSL写入
  • 并发MemTable更新

Java并发


volatile关键字


  • 可见性
  • 进制指令重排
  • 不能保证原子性(i++不是原子操作)

死锁:所有线程都阻塞

//例子:1
private static Integer count = 0;

//例子:2
//为每个线程构造一个实例 private static ThreadLocal<Integer> t = ThreadLocal.withInitial(() -> Integer.valueOf(10));
public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 3; i++) {
        new Thread(() -> {
            count++;
        }).start();
    }
    Thread.sleep(1000);
    System.out.println("count : "+count);
}
  • 使用局部变量可以提高线程的安全性 t.get()方法可以得到属于当前线程的Integer对象。可以看到无论线程中如何操作这个变量,它操作的其实都是属于当前线程的那个实例(局部变量)。

Futrue

-- 实现类FutureTask,实现了Future和Runnable接口。 这个类的构造方法中可以传递一个Callable对象。Callable是一个封装了带有返回值方法的泛型类,返回值类型就是为泛型指定的类型。Future就保存了Callable返回的这个结果。当完成上面的工作之后,就可以将FutureTask对象传到new Thread()构造器,并调用start()运行。

不常用,Future可以保存异步计算结果

创建线程池

执行器Executors类有很多静态方法用来获取线程池

方法描述
newCachedThreadPool必要的时候会创建新的线程;池中的空闲线程会保留60秒
newFixedThreadPool包含固定线程数的线程池;线程会一直保留
newSingleThreadExecutor只包含一个线程,一次只能运行一个任务,排队执行
ExecutorService es = Executors.newFixedThreadPool(16);

//get()可以取出就是结果