【面试专栏】ArrayList 非线程安全案例并提供三种解决方案
1. 复现问题
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* 复现问题
*
* @author CL
*
*/
public class RecurrenceProblem {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
// 启动30个线程
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
运行结果:
[42251c59]
[42251c59, 5839198b]
[42251c59, 5839198b, 1283d17b]
[42251c59, 5839198b, 1283d17b, 01fce852]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea]
Exception in thread "21" [42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea, 0d3b8cf8]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea, 0d3b8cf8, 6fb56487]
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea, 0d3b8cf8, 6fb56487, b9fb25b8]
java.util.ConcurrentModificationException
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea, 0d3b8cf8, 6fb56487, b9fb25b8, 3b98b513]
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
at java.util.ArrayList$Itr.next(ArrayList.java:851)
at java.util.AbstractCollection.toString(AbstractCollection.java:461)
at java.lang.String.valueOf(String.java:2994)
at java.io.PrintStream.println(PrintStream.java:821)
at com.c3stones.demo.RecurrenceProblem.lambda$0(RecurrenceProblem.java:22)
at java.lang.Thread.run(Thread.java:745)
[42251c59, 5839198b, 1283d17b, 01fce852, 857eb6d1, eb874846, 7cfa654c, 794c24d5, 68a415a7, f51c911a, 9f99c03a, 84213b11, b1d1c583, 04ecf6c3, 4d16693d, 65a4715e, e968aa23, b60db864, fb3a9828, 3fd4f004, 333308f6, 7143a717, 9ba40ac6, 06ae20ed, a8aa4fea, 0d3b8cf8, 6fb56487, b9fb25b8, 3b98b513, 83bd3f54]
出现:java.util.ConcurrentModificationException异常
2. 原因剖析
java.util.ConcurrentModificationException即并发修改异常。
查看ArrayList.add(...)源码:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
发现并没有对该方法加锁,因此在并发修改时,必然是线程不安全的,则抛出java.util.ConcurrentModificationException异常。
3. 解决方案
- Vector
使用Vector代替ArrayList。
查看Vector.add(...)源码:
/**
* Appends the specified element to the end of this Vector.
*
* @param e element to be appended to this Vector
* @return {@code true} (as specified by {@link Collection#add})
* @since 1.2
*/
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
可以看到add方法中使用synchronized实现同步。代码修改为:
import java.util.List;
import java.util.UUID;
import java.util.Vector;
/**
* 解决方案01-Vector
*
* @author CL
*
*/
public class Solution01 {
public static void main(String[] args) {
List<String> list = new Vector<String>();
// 启动30个线程
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
运行结果:
[759f9961]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda]
[759f9961, ff871e85, 4a3939a2, 59e796cf]
[759f9961, ff871e85, 4a3939a2]
[759f9961, ff871e85]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931, 12e61627]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931, 12e61627, fa205c82]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931, 12e61627, fa205c82, 04726e78]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931, 12e61627, fa205c82, 04726e78, 0ee9c3d5]
[759f9961, ff871e85, 4a3939a2, 59e796cf, cf4dfbda, bbc62489, 439941c6, 7a003645, fc224a2b, f52573e5, 1144e6c3, 4de11c35, ba2e2d82, 95d9f85e, d4cfdf23, 90dd544b, 59e75219, a3787684, fb5cf421, 9ca37cea, 8cbe36f6, 62494d83, 846001e0, ec1efeaf, 12155931, 12e61627, fa205c82, 04726e78, 0ee9c3d5, 097c1d4e]
从运行结果可以看出,已经解决了问题。但是查看Vector类说明和ArrayList类说明:
/*
* @author Lee Boynton
* @author Jonathan Payne
* @see Collection
* @see LinkedList
* @since JDK1.0
*/
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
}
/*
* @author Josh Bloch
* @author Neal Gafter
* @see Collection
* @see List
* @see LinkedList
* @see Vector
* @since 1.2
*/
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
}
可以看出,Vector是JDK1.0时出现的,ArrayList是JDK1.2出现的。因此,官方肯定不建议使用Vector来解决此问题。
- Collections
使用Collections工具类提供的方法来避免ArrayList出现的并发修改问题。代码修改为:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
/**
* 解决方案02-Collections
*
* @author CL
*
*/
public class Solution02 {
public static void main(String[] args) {
List<String> list = Collections.synchronizedList(new ArrayList<String>());
// 启动30个线程
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
Set、Map在创建实例时也可以使用此方式:
Set<String> set = Collections.synchronizedSet(new HashSet<String>());
Map<Integer, String> map = Collections.synchronizedMap(new HashMap<>());
- CopyOnWrite
CopyOnWrite写时复制。CopyOnWriteArrayList.add(...)方法:
/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return {@code true} (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
可以看出在方法进入时加锁。先创建一个比之前长度大1的数组,并在末尾添加元素,最后再将源容器指向新的容器。这样的好处是源容器不会添加任何元素,这也是一种读写分离的思想。
代码修改为:
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 解决方案03-CopyOnWrite
*
* @author CL
*
*/
public class Solution03 {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<String>();
// 启动30个线程
for (int i = 0; i < 30; i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}, String.valueOf(i)).start();
}
}
}
Set、Map在创建实例时也可以使用此方式:
Set<String> set = new CopyOnWriteArraySet<String>();
Map<Integer, String> map = new ConcurrentHashMap<Integer, String>();
4. 项目地址
【面试专栏】ArrayList 非线程安全案例并提供三种解决方案的更多相关文章
- Vector线程安全,ArrayList非线程安全
http://baijiahao.baidu.com/s?id=1638844080997170869&wfr=spider&for=pc Vector线程安全,ArrayList非线 ...
- net异步线程获取返回值的三种方式
方式一:endInvoke using System; using System.Collections.Generic; using System.Text; using System.Thread ...
- QThread多线程编程经典案例分析(三种方法,解释了为什么使用moveToThread的根本原因,即为了避免调用QThread::exec() )
传统的图形界面应用程序都只有一个线程执行,并且一次执行一个操作.如果用户调用一个比较耗时的操作,就会冻结界面响应. 一个解决方法是按照事件处理的思路: 调用 Void QApplication::pr ...
- Android:在子线程中更新UI的三种方式
①使用Activity中的runOnUiThread(Runnable) ②使用Handler中的post(Runnable) 在创建Handler对象时,必须先通过Context的getMainLo ...
- Java经典案例之用三种方法求1~100以内素数之和
素数,不能被除了1和本身以外整除的数被称为素数.接下来我用三种方式求得1~100以内素数. 方式一 外层每循环一次,内层就计算出这个数有几个因子,我们都知道素数的因子只有两个,所以如果个数为2就加进总 ...
- 面试必备:Java线程池解析
前言 掌握线程池是后端程序员的基本要求,相信大家求职面试过程中,几乎都会被问到有关于线程池的问题.我在网上搜集了几道经典的线程池面试题,并以此为切入点,谈谈我对线程池的理解.如果有哪里理解不正确,非常 ...
- 线程安全 Vs 非线程安全
线程安全:多线程访问时,采用了加锁机制,当一个线程读取数据时,其他线程不能访问直到该线程读取完毕.不会出现数据不一致或者脏数据. 非线程安全:不提供数据保护,可能出现其他线程访问时更改数据而该线程得到 ...
- 集合不安全之 ArrayList及其三种解决方案【CopyOnWriteArrayList 、synchronizedList、Vector 】
@ 目录 一.前言 二.为什么线程不安全 三.解决方案一CopyOnWriteArrayList (推荐,读多写少场景) 四.Collections.synchronizedList(加锁) 五.Ve ...
- Java并发编程:Java创建线程的三种方式
目录 引言 创建线程的三种方式 一.继承Thread类 二.实现Runnable接口 三.使用Callable和Future创建线程 三种方式的对比 引言 在日常开发工作中,多线程开发可以说是必备技能 ...
随机推荐
- 在 macOS 中使用 Podman
原文链接:https://fuckcloudnative.io/posts/use-podman-in-macos/ Podman 是一个无守护程序与 Docker 命令兼容的下一代 Linux 容器 ...
- 把token放入请求头
1.jq 2.vue.js
- 吉他自学用Guitar Pro好不好?
很多人心中都有一个吉他梦,可苦于没有坚持下来.其实一个人自学吉他过程是非常枯燥的.经常手上被磨得都是茧,但是也不清楚自己弹的到底对不对. 如果不跟着老师练习,那很有可能就走了歪路或者是无法长期坚持.所 ...
- word查找与替换
------------恢复内容开始------------ 如何快速删除大量空格键:查找和替换-更多-特殊格式-查找内容[特殊格式(段落标记)]设置为(^p^p,即点击两次段落标记),替换设置为(^ ...
- Lambda表达式(一)入门认识篇
Lambda表达式(一)入门认识篇 Lambda简介 Lambda 表达式是 JDK8 的一个新特性,可以取代大部分的匿名内部类,写出更优雅的 Java 代码,尤其在集合的遍历和其他集合操作中,可以极 ...
- JUC并发工具包之Semaphore
目录 Semaphore (JDK) Timed Semaphore (Apache Commons) Semaphore vs. Mutex CodeRepo Semaphore (JDK) 我们使 ...
- 接入twitter第三方登陆接口遇到的一个问题
本地开了 Shadowsocks,然后postman模拟的twitter的接口是请求成功的,然后用php-curl去请求网址,出现以下错误 Failed to connect to api.twitt ...
- 用大白话讲大数据HBase,老刘真的很用心(1)
老刘今天复习HBase知识发现很多资料都没有把概念说清楚,有很多专业名词一笔带过没有解释.比如这个框架高性能.高可用,那什么是高性能高可用?怎么实现的高性能高可用?没说! 如果面试官听了你说的,会有什 ...
- window consul安装和运行
consul 前言 一.consul是什么? 二.使用步骤 1.安装 2.启动 结束~~ 前言 刚开始接触spring cloud,其中就有用到consul,简单介绍一下以及怎么安装运行起来 提示:以 ...
- 基于gin的golang web开发:docker
Golang天生适合运行在docker容器中,这得益于:Golang的静态编译,当在编译的时候关闭cgo的时候,可以完全不依赖系统环境. 一些基础 测试容器时我们经常需要进入容器查看运行情况,以下命令 ...