场景:某个集合正在被遍历的时候,给集合加入新元素,这个时候是会抛并发修改异常还是正常?如果正常的话,能不能拿到新获取的元素?
KeySetView
public class concurrentTest {
public static void main(String[] args) {
Set<String> channels = ConcurrentHashMap.newKeySet();
channels.add("haha");
channels.add("hehe");
new Thread(new Runnable() {
@Override
public void run() {
try{
Thread.sleep(1500);
channels.add("lulu");
System.out.println("add lulu:" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}).start();
channels.forEach(
s -> {
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
);
}
}
在KeySetView初始化后 遍历过程中加入的元素,都不会被访问到。
HashSet
public static void main(String[] args) {
Set<String> channels = new HashSet<>();
channels.add("haha");
channels.add("hehe");
new Thread(new Runnable() {
@Override
public void run() {
try{
Thread.sleep(3000);
channels.add("lulu");
System.out.println("add lulu:" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}).start();
channels.forEach(
s -> {
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
);
}
for (String s: channels) {
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
Iterator<String> iter = channels.iterator();
while (iter.hasNext()) {
String s = iter.next();
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
public static void main(String[] args) {
Set<String> channels = new HashSet<>();
channels.add("haha");
channels.add("hehe");
new Thread(new Runnable() {
@Override
public void run() {
try{
Thread.sleep(3000);
channels.remove("hehe");
System.out.println("rm hehe:" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}).start();
/* channels.forEach(
s -> {
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
);*/
/* for (String s: channels) {
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}*/
Iterator<String> iter = channels.iterator();
while (iter.hasNext()) {
String s = iter.next();
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
iter = channels.iterator();
while (iter.hasNext()) {
String s = iter.next();
try {
Thread.sleep(2000);
System.out.println(s + ":" + System.currentTimeMillis());
} catch (InterruptedException e) {
}
}
}
并发锁测试
public class conTest1 {
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
printC();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
printB();
}
}
}).start();
}
public static void printA() {
synchronized (lock) {
while (true) {
try {
Thread.sleep(1000);
System.out.println("A");
} catch (InterruptedException e) {
}
}
}
}
public static void printB() {
synchronized (lock) {
System.out.println("B");
}
}
public static void printC() {
synchronized (lock) {
System.out.println("C");
}
}
}
-
相同锁对象时,B和C交替拿锁,A拿到锁后,B就执行拿不到锁了,执行不了;
-
如果A和B拿的是不同的锁对象,那么A和B都可以执行