1.传值与传引用
深拷贝+浅拷贝
对象拷贝(Object Copy)就是将一个对象的属性拷贝到另一个有这相同类类型的对象中去。
在程序中靠背对象是很常见的,主要是为了在新的上下文环境中复用对象的部分或全部数据。
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存,类似一个分支。
拷贝基本类型:拷贝的就是基本类型的值。
拷贝引用类型:拷贝的就是内存地址,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。
一句话,多个引用指向同一个对象,如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝:会另外创建一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,分灶吃饭截然不同,深拷贝则是拷贝了原对象的所有值,所以及时原对象的值发生变化时,拷贝对象的值也不会改变。
JUC多线程高并发实战案例: ThreadLocal提供线程局部变量。这些变量与正常的变量不同,因为每一个线程在访问ThreadLocal实例的时候(通过气get或set方法)都有自己的,独立初始化的变量副本。ThreadLocal实例通常是类中的私有静态字段,使用他的目的是希望将状态(例如,用户ID或事务ID)与线程关联起来。
1. ThreadLocal可以在当前线程中共享数据,set/get需要在同一个线程中执行才行,别人的取不到。父线程无法传递给子线程。(自己独立)
2. InheritableThreadLocal inheritableThreadLocal = new InheritableThreadLocal(); 使用InheritableThreadLocal,子线程可以获得父线程set进去的值(自己独立+可以父子传递)
- TransmittableThreadLocal(线程池共享+自己传递+父子传递) 功能最为强大。
线程池如何正确关闭。 如果要求不高的话,直接就是线程的threadpool.shutdown(); threadPool.shutdownNow();
执行shutdown方法或shutdownNow方法之后,将会影响任务的状态。
任务状态:1.未提交,此时可以将任务提交到线程池。2.已提交未执行,此时任务已在线程池的队列中,等待着执行。3.执行中,此时任务正在执行4.执行完毕。
下面代码中,1-5个任务正常被执行。所以shutdown方法将线程池状态置为shutdown,线程池并不会立即停止,要等正在执行和队列中等待的任务执行完才会停止。
不会等已提交的任务(即等待队列中的任务)完成执行,让awaitTermination来实现这个功能。
shutdownNow源码中,是通过interrupt方法种植正在运行的任务的,因此无法响应interrupt中断的任务可能不会被终止。所以该方法是无法保证一定能种植任务的。
调用shutdownNow后,第一个任务正在睡眠的时候,触发了interrupt中断。之前等待的任务2-5被从队列中清除并返回,之后的任务6~10被拒绝 but shutdownNow 方法将线程池状态置为stop,试图让线程池立刻停止,但不一定能保证立即停止,要等所有正在执行的任务(不能被interrupt中断的任务)执行完才能停止。
不会等已提交的任务(即等待队列中的任务)完成执行,让awaitTermination来实现这个功能。
总结:shutdown和shutdownNow都不会等待任务执行完毕。 如果需要等待,要使用awaitTermination。awaitTermination带有超时参数:如果超时后任务仍然未执行完毕,也不再等待。
毕竟应用总归要停机重启,而不可能无限等待下去,因此超时机制是提供给用户的最后一道底线。