Java多线程消费一个list
在项目中,常常会需要处理一个list数据列表,使用多线程来加速数据的处理。
需要保证两点:
- 能灵活控制线程的数量
- 能够同步的完成一批list的数据
可以使用信号量和线程池,具体实现代码如下:
1 | public static <T> void startWithMultiThread(List<T> list, int nThread, Consumer<T> func) { |
在项目中,常常会需要处理一个list数据列表,使用多线程来加速数据的处理。
需要保证两点:
可以使用信号量和线程池,具体实现代码如下:
1 | public static <T> void startWithMultiThread(List<T> list, int nThread, Consumer<T> func) { |
对于进程和线程的概念可以简单的理解成一个包含关系,例如:一个人个体可以称为社会的一个进程
,人可以同时做很多事情,这个称之为线程
CPU一次只能执行一个指令,操作系统为了保证同一时刻多个程序同时执行, 把每次执行的指令过程分成若干时间片(timeslice)
,每一个程序都会在指定的时间片上运行一段时间后,然后保存运行的上下文资源,来保证下次执行。
由于进程对于资源的需求比较多,保存和恢复都会需要很多时间,CPU每次执行的单位都是线程
。
所以单核的CPU的执行其实本质都是单线程
.
例如我们同时运行A、B、C三个程序:
疑问:如果是多线程本质还是单线程执行为什么我们还要使用多线程?
因为在程序执行的过程的中,CPU的执行速度大于内存,也远远大于磁盘IO的运算,如果一个程序CPU执行完成后,要等待磁盘和内存的读取。在等待期间,CPU处于空闲的状态,这样就导致的资源的浪费。
多线程的引入是在CPU存在空闲的时间片的时候,能够有指令被执行,不必再等待其他的执行。
在python
中,枚举使用Enum
模块。 具体使用如下:
1 |
|
在枚举中可以自动为下面的变量赋值,我们可以使用迭代把数据显示出来:
1 | from enum import Enum |
打印结果:
1 | Mon : Week.Mon , 1 |
如果像自定义枚举的值,可以使用继承的方法,自定义一个枚举:
1 | from enum import Enum, unique |
打印结果:
python
的函数也属于一个对象,可以有一个变量来代替,例如前面说过的一个例子:
1 | f=abs |
打印结果是:
1 | do something |
对于上面的代码,new_func
就是装饰器,可以使用@
对其进行简化:
1 | def new_func(func): |
打印结果:
1 | do something |
我们再增加一个方法:
1 | @new_func |
函数式编程
主要思想是把运算过程尽量写成一系列嵌套的函数调用,不严谨的说:可以把函数的引用传递给变量。
例如:
1 | >>> abs(-10) |
函数也可以当成返回值:
1 | def getMethod(): |
打印结果是:1
python也支持lambda
表达式
1 | f=lambda x:x+x |
打印结果是:10
可以固定一个函数的默认值,返回一个新函数
1 | import functools |
python
使用def
来定义
1 | def print_str(x): |
当调用print_str(1,2)
,打印结果:1
2
3
4
5
6
7
8
9
10x: 1
y: 2
z: z
```
当调用`print_str(1,z=2)`,打印结果:
``` cte
x: 1
y: y
z: 2
使用默认参数需要注意一个问题:默认定义的时候,默认参数值已近计算出来
,如果是一个默认参数是一个引用,则会发生改变。
1 | def add_dict(arr=[]): |
所以,如果使用可变的引用变量,则注意这种形式。可以使用None
来代替:
1 | def add_dict(arr=None): |
定义一个数组
1 | arr=list(range(100)) |
数组取前3个元素 arr[0:3]
,0可以省略,arr[:3]
,打印结果:[0,1,2]
数组取后面三个元素: arr[-3:0]
,也可写为:arr[-3:]
,打印结果:[97,98,99]
arr[97:]
,是跳过前97个数字,打印结果:[97,98,99]
可以指定取值的间隔 arr[:10:2]
,打印结果:[0, 2, 4, 6, 8]
如果在全部范围内查询,可以省略查询的个数,arr[::2]
这样打印出来所有的偶数。
切片的方法同样适用于tuple
字符串可以看成是字符的数组,可以使用,"ABCDEFG"[:3]
输出结果ABC
list
的循环
1 | arr=list(range(10)) |
字符串循环
1 | for a in "ABCD": |
带索引的循环写法
1 | for i, value in enumerate(['A', 'B', 'C']): |
判断能否被迭代
1 | from collections import Iterable |
列表生成式可以更简单的把生成一个list
或者tuple
.
定义一个100的数组,arr=list(range(100))
定义一个100偶数的数组
1 | arr=[2 * x for x in list(range(100))] |
打印结果:[0,2,4...198]
定义两个循环生成一个组合
1 | str=[a+b for a in "ABC" for b in "XYZ"] |
打印结果:['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
使用多个变量
1 | dict = {'a': 'A', 'b': 'B', 'c': 'C' } |
打印结果:0,2,4,6,8
也可以使用循环打印:
1 | g = (2 * x for x in range(10)) |
最近想学下数学方面的东西,但发现公式的插入是比较头疼的事情。在Markdown
的环境下,有一个latex数学公式
官网的写法,用起来很是强大,只要引入下面的js就可以。
1 | <script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML' async></script> |
以…x_{11}$$ ,具体的写法如下:1
$$x_{11}$$
|字母|公式||字母|公式|
||\pi\beta\Sigma\gamma\Gamma\delta\Delta\epsilon\varphi\eta\upsilon\phi\Phi\omega\Omega\theta\Theta\lambda\Lambda\mu\nu\xi\partial$$|$$$\partial$$$|
|字母|公式||字母|公式|
||\sqrt[x]yxix{ij}\dots\cdots$$|$$$\cdots$$$|
四则运算符(operator) 例如 + - * /等可以直接输入
|字母|公式||字母|公式|
||\times\cap\cup\geq\leq\neq\approx\sum{i=0}^nx_iy_i$$|$$$\sum{i=0}^nxiy_i\sum_1^n\int_1^n\lim{x \to \infty}\frac{y}{x}\equiv$$|$$$\equiv$$$|
在python
有一个dict类型,存储格式是key:value
的形式,在其他语言有的成为map
和Dictionary
.
1 | >>> dict={"a":1,"b":3} |
由于dict
是根据key查询数据,所以查询的效率比list
要高出不少。
取值的时候,key如果不存在则会报异常。所以为了更安全的使用dict
可以使用前判断下:
1 | >>> "a" in dict |
或者可以使用get
函数,如果不存在,则返回None
数据,也可以指定默认值:
1 | >>> dict.get("c") |
- dict的key必须是不可变对象
- dict的内部顺序和存储的先后顺序没有关系
- 查找和插入的速度极快,不会随着key的增加而变慢
- 需要占用大量的内存,内存浪费多。
dict
可以使用pop
方法对数据进行删除: