解决Aaraylist线程不安全,以及八种锁的现象

/**
*题目:请举例说明集合类是不安全的
* 1,故障现象:
* java.util.ConcurrentModificationException
* 2,导致原因
*
* 3,解决方案
* 3.1 vector
* 3.2 Collection.synchronizedList();
* 3.3 new CopyOnWriteArraylist();
*
* 4,优化建议(同样的错误,不出现第二次)
*/
public class NotSafeDemo {
public static void main(String[] args) {
List<String> list= Collections.synchronizedList(new ArrayList<>()); //new ArrayList<String >();
for(int i=1;i<=30;i++) {
new Thread(() -> {
list.add(UUID.randomUUID().toString().substring(0,8));
System.out.println(list);//一边写一边读
}, String.valueOf(i)).start();
}
}
//笔记:
/*
* 写时复制:
* copyOnWrite容器即写时复制的容器,往一个容器添加元素的时候,不直接往当前容器object[]
* 添加,而是先将当前容器object[]进行copy,
* 复制出一个新的容器object[] newElements,然后新的容器object[] newElements里面添加元素,添加完元素之后,
* 再将原容器的引用指向新的容器,setArray(newArrays);这样做的好处是可以copyonWrite容器进行并发的读,
* 而不需要加锁,因为当前容器不会添加任何元素。所以copyOnwrite容器也是一种读写分离的思想,读和写不同的容器
*
* */
}
---------------------------------------------------------------------------------------------------------------------------------
public class Lock8 {
public static void main(String[] args) {
Phone phone=new Phone();
new Thread(()->{
try {
phone.sendEmail();
}catch (Exception e){
}
},"A").start();
/* try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
new Thread(()->{
try {
phone.sendHello();
}catch (Exception e){
}
},"B").start();
}
}
class Phone{
public synchronized void sendEmail() throws Exception{
try {
TimeUnit.SECONDS.sleep(4);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("-----sendEmail");
}
public synchronized void sendSMS() throws Exception{
System.out.println("-----sendSMS");
}
public void sendHello()throws Exception{
System.out.println("-----sendHello");
}
}
/*
* 题目:多线程8锁
* 1,标准访问,请问先打印邮件还是短信?邮件,短信
* 2,邮件方法暂停4秒钟,请问先打印邮件还是短信?邮件,短信
* 解释:一个对象里面如果有多个synchronized方法,某一时刻线程去调用其中一个的esynchronized方法了,
* 其它的线程都只能等待,换句话说,某一时刻内,只能有唯一一个线程去访问这些synchronized方法
* 锁的是当前对象this,被锁定后,其它的线程都不能进入到当前的其它的synchronized方法
* 3,新增一个普通方法hello(),请问先打印邮件还是hello?
* 4,两部手机,请问先打印邮件还是短信?
* 5,两个静态同步方法,同一部手机,请问先打印邮件还是短信?
* 6,两个静态方法,两个手机,请问先打印邮件还是短信?
* 7,1个普通同步方法,1个静态同步方法,1部手机,请问先打印邮件还是短信?
* 8,一个普通同步方法,1个静态同步方法,2部手机,请问先打印邮件还是短信?
* 加一普通方法后发现和同步锁无关
* 换成两个对象后,不是同一把锁了,情况立刻变化。
* 都换成静态同步方法后,情况又变化
* 所有的非静态同步方法用的都是同一把锁即实例对象本身
* synchronized实现同步的基础:Java中的每一个对象都可以作为锁。
* 具体表现为以下3种形式。
* 对于普通同步方法,锁是当前实例对象。
*
**/
原文地址:https://www.cnblogs.com/shanbaoxin/p/11660559.html