Skip to content

Commit

Permalink
更新代码
Browse files Browse the repository at this point in the history
  • Loading branch information
UCodeUStory committed May 14, 2019
1 parent bb356e1 commit 7937305
Show file tree
Hide file tree
Showing 14 changed files with 684 additions and 310 deletions.
620 changes: 319 additions & 301 deletions .idea/workspace.xml

Large diffs are not rendered by default.

18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,30 @@
- [Java 实现LRU缓存3种方式 ](https://github.com/UCodeUStory/DataStructure/blob/master/sources/lru.md)
- [LinkHashMap 实现FIFO](https://github.com/UCodeUStory/DataStructure/blob/master/sources/fifo.md)
- [Java 集合原理](http://wiki.jikexueyuan.com/project/java-collection/hashset.html)
- [synchronized 和 Lock区别](https://github.com/UCodeUStory/DataStructure/blob/master/sources/synchronized_lock.md)
- [wait 和 sleep区别](https://github.com/UCodeUStory/DataStructure/blob/master/sources/wait_sleep.md)
- [yield()和join()](https://github.com/UCodeUStory/DataStructure/blob/master/sources/yield_join.md)
- [HashMap冲突](https://github.com/UCodeUStory/DataStructure/blob/master/sources/hash_confict.md)
- [Java 8十大特性](https://github.com/UCodeUStory/DataStructure/blob/master/sources/java8.md)
- [Java 克隆](https://github.com/UCodeUStory/DataStructure/blob/master/sources/javaCopy.md)
- [Java foreach原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/foreach.md)
- [synchronized 和 Lock区别](https://github.com/UCodeUStory/DataStructure/blob/master/sources/synchronized_lock.md)
- [BlockingQueue和BlockingDequeu详解](https://github.com/UCodeUStory/DataStructure/blob/master/sources/blockqueue.md)
- [锁类型详解](https://github.com/UCodeUStory/DataStructure/blob/master/sources/locktype.md)
- [Condition实现对锁进行更精确的控制](https://github.com/UCodeUStory/DataStructure/blob/master/sources/condition.md)
- [LinkBlockingQueue原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/linkblockingqueue.md)
- [多个线程安全的原子化操作组合将不再是安全的](https://github.com/UCodeUStory/DataStructure/blob/master/sources/automizationoperation.md)
- [CopyOnWriteArrayList原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/copyOnWriteArrayList.md)
- [ConcurrentHashMap原理]
- [Java NIO]
- [ConcurrentHashMap原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/concurrentHashMap.md)
- [分布式锁-分段锁思想]()
- Java NIO

#### Android 常见问题
1. [Volley源码分析经典算法](https://github.com/UCodeUStory/DataStructure/blob/master/sources/volley_algorithm.md)
2. [Android Design Support Library包含内容](https://github.com/UCodeUStory/DataStructure/blob/master/sources/adsl.md)
3. [Android v4 v7 v8 v13区别](https://github.com/UCodeUStory/DataStructure/blob/master/sources/v4_v7_v8_v13.md)
4. [Android Design Support Library V28 新增加内容](https://github.com/UCodeUStory/DataStructure/blob/master/sources/design_v28.md)
5. [Android网络数据安全](https://github.com/UCodeUStory/DataStructure/blob/master/sources/netsafe.md)
6. [Binder 原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/Binder.md)
6. [Android Binder 原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/binder.md)
7. [Android应用架构设计](https://github.com/UCodeUStory/DataStructure/blob/master/sources/frame.md)
8. [热修复技术和原理](https://github.com/UCodeUStory/DataStructure/blob/master/sources/hotfix.md)
9. [Android 8.0 WorkManager后台任务可以保活](https://github.com/UCodeUStory/DataStructure/blob/master/sources/workManager.md)
Expand All @@ -113,21 +114,22 @@
25. [多进程Application初始化问题](https://github.com/UCodeUStory/DataStructure/blob/master/sources/application.md)
26. [Application可以开线程替换Service处理后台任务吗](https://github.com/UCodeUStory/DataStructure/blob/master/sources/application_service.md)
27. [android.os.killProcess和System.exit(0)区别](https://github.com/UCodeUStory/DataStructure/blob/master/sources/killprocess_system_exit.md)
28. 线程通信
28. [线程通信有哪些方式](https://github.com/UCodeUStory/DataStructure/blob/master/sources/thread_communication_way.md)
29. [ConstraintLayout 完全解析 快来优化你的布局](https://blog.csdn.net/lmj623565791/article/details/78011599?utm_source=tuicool&utm_medium=referral)
30. [Android 匿名共享内存原理](https://www.jianshu.com/p/d9bc9c668ba6)
31. [Binder 原理深度剖析](https://github.com/UCodeUStory/DataStructure/blob/master/sources/binder.md)
32. [MediaPlayer生命周期](https://github.com/UCodeUStory/DataStructure/blob/master/sources/media_player.md)
33. [TransactionTooLargeException解决方法](https://github.com/UCodeUStory/DataStructure/blob/master/sources/transactiontoolargeexception.md)
34. [谈一下Http请求过程](https://github.com/UCodeUStory/DataStructure/blob/master/sources/http.md)
35. [Android 进程通信种类](https://github.com/UCodeUStory/DataStructure/blob/master/sources/androidipc.md)
#### 设计模式
1. [面向对象的七种设计原则](https://github.com/UCodeUStory/DataStructure/blob/master/sources/seven_design_principles.md)
2. [建造者模式](https://github.com/UCodeUStory/DataStructure/blob/master/sources/kotlin/builderModel.kt)

#### Android 框架使用说明
1. [rxjava使用](https://github.com/UCodeUStory/DataStructure/blob/master/sources/rxjavademo.md)
2. [liveData](https://github.com/UCodeUStory/DataStructure/blob/master/sources/livedata.md)
3. [rxCache]
1. [Rxjava使用](https://github.com/UCodeUStory/DataStructure/blob/master/sources/rxjavademo.md)
2. [LiveData](https://github.com/UCodeUStory/DataStructure/blob/master/sources/livedata.md)
3. [RxCache]

##### Android框架源码分析
1. [EventBus源码分析](https://github.com/UCodeUStory/DataStructure/blob/master/sources/eventbus.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
Expand Down Expand Up @@ -57,6 +58,7 @@ protected String getSummaryData() {
public ListNode addTwoNumber(ListNode l1,ListNode l2){

CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
ConcurrentHashMap map = new ConcurrentHashMap(10);
return null;

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.wangpos.datastructure.java.semaphore


fun main() {


}
58 changes: 58 additions & 0 deletions app/src/main/java/com/wangpos/datastructure/java/thread/Helper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.wangpos.datastructure.java.thread

import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

/**
* Created by Edison Xu on 2017/3/2.
*/
enum class Helper {

instance;

fun run(r: Runnable) {
tPool.submit(r)
}

fun shutdown() {
tPool.shutdown()
}

companion object {

private val tPool = Executors.newFixedThreadPool(2)

fun buildNoArr(max: Int): Array<String?> {
val noArr = arrayOfNulls<String>(max)
for (i in 0 until max) {
noArr[i] = Integer.toString(i + 1)
}
return noArr
}

fun buildCharArr(max: Int): Array<String?> {
val charArr = arrayOfNulls<String>(max)
val tmp = 65
for (i in 0 until max) {
charArr[i] = (tmp + i).toChar().toString()
}
return charArr
}

@JvmStatic
fun printString(input: String) {
input?.let {
print(input)
}
}

@JvmStatic
fun print2String(input: String, input2: String) {
if (input == null)
return
print(input)
print(input2)
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.wangpos.datastructure.java.thread

import kotlin.concurrent.thread

fun main() {

val messageBridge = MessageBridge()

thread(true) {
println(messageBridge.doSomeThing())
}
thread(true) {
println(messageBridge.doSomeThing2())

}

}


class MessageBridge {

var message: Int = 0

@Synchronized
fun doSomeThing(): Int {
message++
return message
}

@Synchronized
fun doSomeThing2(): Int {
message++
return message
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package com.wangpos.datastructure.java.thread

import java.util.*


fun main() {
val one = MethodOne()
Helper.instance.run(one.newThreadOne())
Helper.instance.run(one.newThreadTwo())
Helper.instance.shutdown()
}

/*8
1. 第一种解法,包含多种小的不同实现方式,但一个共同点就是靠一个共享变量来做控制;
a. 利用最基本的synchronized、notify、wait:
*/



class MethodOne {
private val threadToGo = ThreadToGo()

fun newThreadOne(): Runnable {
val inputArr = Helper.buildNoArr(52)
println(Arrays.toString(inputArr))
return Runnable {
try {
var i = 0
while (i < inputArr.size) {
synchronized(threadToGo) {
while (threadToGo.value == 2)
threadToGo.wait()
Helper.print2String(inputArr[i]!!, inputArr[i + 1]!!)
threadToGo.value = 2
threadToGo.notify()
}
i += 2
}
} catch (e: InterruptedException) {
println("Oops...")
}
}
}

fun newThreadTwo(): Runnable {
val inputArr = Helper.buildCharArr(26)
println(Arrays.toString(inputArr))
return Runnable {
try {
for (i in inputArr.indices) {
synchronized(threadToGo) {
while (threadToGo.value == 1)
threadToGo.wait()
Helper.printString(inputArr[i]!!)
threadToGo.value = 1
threadToGo.notify()
}
}
} catch (e: InterruptedException) {
println("Oops...")
}
}
}

internal inner class ThreadToGo:java.lang.Object() {
var value = 1
}


}
19 changes: 19 additions & 0 deletions sources/androidipc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
### Android 进程通信方式


一、使用 Intent (startActivity startService sendBroadcast)
二、使用文件共享 (SharePreference)
三、使用 Messenger
四、使用 AIDL
五、使用 ContentProvider
六、使用 Socket



Messenger

1. Messenger本质也是AIDL,只是进行了封装,开发的时候不用再写.aidl文件。
结合我自身的使用,因为不用去写.aidl文件,相比起来,Messenger使用起来十分简单。但前面也说了,Messenger本质上也是AIDL,故在底层进程间通信这一块,两者的效率应该是一样的。

2. 在service端,Messenger处理client端的请求是单线程的,而AIDL是多线程的。
使用AIDL的时候,service端每收到一个client端的请求时,就会启动一个线程(非主线程)去执行相应的操作。而Messenger,service收到的请求是放在Handler的MessageQueue里面,Handler大家都用过,它需要绑定一个Thread,然后不断poll message执行相关操作,这个过程是同步执行的。
40 changes: 40 additions & 0 deletions sources/concurrentHashMap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
### JDK 1.5 1.8 ConcurrentHashMap 源码剖析


#### ConcurrentHashMap 是一个并发散列映射表的实现,它允许完全并发的读取,并且支持给定数量的并发更新。相比于 HashTable 和同步包装器包装的 HashMap,使用一个全局的锁来同步不同线程间的并发访问,同一时间点,只能有一个线程持有锁,也就是说在同一时间点,只能有一个线程能访问容器,这虽然保证多线程间的安全并发访问,但同时也导致对容器的访问变成串行化的了。

1.6中采用ReentrantLock 分段锁的方式,使多个线程在不同的segment上进行写操作不会发现阻塞行为;

1.8中直接采用了内置锁synchronized,难道是因为1.8的虚拟机对内置锁已经优化的足够快了?


1.6 分段锁技术,细粒度划分锁,每一个数据一把锁

public class MyConcurrentHashMap<K,V> {
private final int LOCK_COUNT = 16;
private final Map<K,V> map;
private final Object[] locks ;

public MyConcurrentHashMap() {
this.map = new HashMap<K,V>();
locks = new Object[LOCK_COUNT];
for (int i=0;i<LOCK_COUNT;i++){
locks[i] = new Object();
}
}

private int keyHashCode(K k){
return Math.abs(k.hashCode() % LOCK_COUNT);
}

public V get(K k){
int keyHashCode = keyHashCode(k);
synchronized (locks[keyHashCode % LOCK_COUNT]){
return map.get(k);
}
}

}


1.8
1 change: 1 addition & 0 deletions sources/javaconcurrent/java_core_semaphore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
###
20 changes: 20 additions & 0 deletions sources/javaconcurrent/program_english.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@


### 比较难读的英文单词

- synchronized

- AsyncTask

- semaphore

- reentrantLock

- concurrentHashMap

- condition

- segment

- volatile

11 changes: 10 additions & 1 deletion sources/locktype.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,16 @@ CAS与synchronized的使用情景
读写锁既是互斥锁,又是共享锁,read模式是共享,write是互斥(排它锁)的。
读写锁有三种状态:读加锁状态、写加锁状态和不加锁状态

Java 中概念
- 可重入锁

可重入锁的概念是自己可以再次获取自己的内部锁。举个例子,比如一条线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的(如果不可重入的锁的话,此刻会造成死锁)。说的更高深一点可重入锁是一种递归无阻塞的同步机制。对于Java ReentrantLock而言, 他的名字就可以看出是一个可重入锁,其名字是Reentrant Lock重新进入锁。对于Synchronized而言,也是一个可重入锁。可重入锁的一个好处是可一定程度避免死锁。

- 独享锁/共享锁

独享锁是指该锁一次只能被一个线程所持有。共享锁是指该锁可被多个线程所持有。对于Java ReentrantLock(互斥锁)而言,其是独享锁。但是对于Lock的另一个实现类ReadWriteLock(读写锁),其读锁是共享锁,其写锁是独享锁。读锁的共享锁可保证并发读是非常高效的,读写,写读 ,写写的过程是互斥的。对于Synchronized而言,当然是独享锁。


- Java 中概念

-- 同步锁 在java中,每一个对象有且仅有一个同步锁。这也意味着,同步锁是依赖于对象而存在。一般使用 使用synchronized关键字来实现

Expand Down
30 changes: 30 additions & 0 deletions sources/segmentLock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

### 分段加锁思想。


**电商公司:假如下单时,用分布式锁来防止库存超卖,但是是每秒上千订单的高并发场景,如何对分布式锁进行高并发优化来应对这个场景?
在实际落地生产的时候,分布式锁这个东西保证了数据的准确性,但是他天然并发能力有点弱**


假如你现在iphone有1000个库存,那么你完全可以给拆成20个库存段,要是你愿意,可以在数据库的表里建20个库存字段,每个库存段是50件库存,比如stock_01对应50件库存,stock_02对应50件库存。类似这样的,也可以在redis之类的地方放20个库存key。

接着,1000个/s 请求,用一个简单的随机算法,每个请求都是随机在20个分段库存里,选择一个进行加锁。

每个下单请求锁了一个库存分段,然后在业务逻辑里面,就对数据库或者是Redis中的那个分段库存进行操作即可,包括查库存 -> 判断库存是否充足 -> 扣减库存。

相当于一个20毫秒,可以并发处理掉20个下单请求,那么1秒,也就可以依次处理掉20 * 50 = 1000个对iphone的下单请求了。

一旦对某个数据做了分段处理之后,有一个坑一定要注意:就是如果某个下单请求,咔嚓加锁,然后发现这个分段库存里的库存不足了,此时咋办?

这时你得自动释放锁,然后立马换下一个分段库存,再次尝试加锁后尝试处理。 这个过程一定要实现。

#### 分布式锁并发优化方案的不足

最大的不足,很不方便,实现太复杂。

- 首先,你得对一个数据分段存储,一个库存字段本来好好的,现在要分为20个分段库存字段;
- 其次,你在每次处理库存的时候,还得自己写随机算法,随机挑选一个分段来处理;
- 最后,如果某个分段中的数据不足了,你还得自动切换到下一个分段数据去处理。
这个过程都是要手动写代码实现的,还是有点工作量,挺麻烦的。

不过我们确实在一些业务场景里,因为用到了分布式锁,然后又必须要进行锁并发的优化,又进一步用到了分段加锁的技术方案,效果当然是很好的了,一下子并发性能可以增长几十倍
Loading

0 comments on commit 7937305

Please sign in to comment.