JUC并发

进程和线程的区别

进程:指在系统中正在运行的一个应用程序,程序一旦运行就是一个进程,进程是资源分配的最小单位

线程:系统分配处理器时间资源的基本单位,或者说进程之内独立执行的一个单元执行流,线程是程序执行的最小单位

 

wait和sleep的区别

1.sleep是Thread的静态方法,wait是Object的方法,任何实例对象都可以调用

2.sleep不释放锁,也不会占用锁,wait会释放锁,调用它的前提是当前线程占有锁(即代码要在synchronized中)

3.都可以被interrupted方法中断

 

并行和并发的区别

并发:同一时刻多个线程访问同一个资源 例如:春运抢票,电商秒杀

并行:多项工作一起执行,之后再汇总 例如:泡方便面,电水壶烧水,一遍撕调料倒入桶中

 

Lock和Synchronized的区别

1.Lock是一个接口,synchronized是Java的关键字

2.synchronized发生异常时,会自动释放线程占用的锁,不会导致死锁,Lock发生异常时,如果没有主动的去释放锁,很有可能造成死锁,因此Lock需要在finally中释放锁

3.Lock可以让等待锁的线程响应中断,synchronized会让线程一直等下去

4.通过Lock可以知道有没有成功获取锁,synchronized无法办到

5.Lock可以提高多个线程进行读写作的效率,从性能上来说,当竞争资源不激烈时,两者性能都差不多,当竞争激烈时,Lock的性能远远大于synchronized

 

ArrayList线程不安全及解决方案

ArrayList里的add方法没有加synchronized修饰,一边放一边去,会导致并发修改异常

解决方案1:

  使用Vector,因为它的add方法加了synchronized修饰

解决方案2:

  使用Collection.synchronizedList方法

解决方案3:

  使用CopyOnWriteArrayList(写时复制技术),兼顾到了并发读以及独立写的操作

 

HashSet线程不安全及解决方案

HashSet里的add方法没有加synchronized修饰,一边放一边去,会导致并发修改异常

解决方案:

  使用CopyOnWriteArraySet(写时复制技术),兼顾到了并发读以及独立写的操作

 

HashMap线程不安全及解决方案

HashMap里的put方法没有加synchronized修饰,一边放一边去,会导致并发修改异常

解决方案:

  使用ConcurrentHashMap,兼顾到了并发读以及独立写的操作

 

死锁

两个或者两个以上的线程在执行过程中,因为抢夺资源而造成的一种互相等待的现象,如果没有外力干涉,它们无法再执行下去

产生死锁的原因:

  1.系统资源不足

  2.进程运行推进顺序不合适

  3.资源分配不当

验证是否死锁:

  1.jps

  2.linux ps -ef

  3.jstack (JVM自带的堆栈跟踪工具)

 

读锁和写锁

读锁:共享锁,发生死锁

  JUC并发

  线程1修改的时候,需要等待线程2读完

  线程2修改的时候,需要等待线程1读完

写锁:独占锁,发生死锁

  JUC并发

  线程1对第一条记录进行写操作,也可以对第二条记录进行写操作

  线程2对第二条记录进行写操作,也可以对第一条记录进行写操作

缺点:

  造成锁饥饿,一直进行读操作,没有写操作

  读的时候不能写

优点:

  可以一起读

 

异步回调

public class CompletableFutureDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        
        //无返回值
        CompletableFuture<Void> completableFuture1 = CompletableFuture.runAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "completableFuture1");
        });
        completableFuture1.get();

        //有返回值
        CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName() + "completableFuture2");
            return 1024;
        });
        //t:返回值 u:异常信息
        completableFuture2.whenComplete((t,u) ->{
            System.out.println("-------t"+t);
            System.out.println("-------u"+u);
        }).get();
    }
}

 

上一篇:设值Execl单元格颜色,以及字体颜色


下一篇:PHP 记录一下 AJAX导出EXECL