🐓 sleep和wait区别
1.sleep方法
属于Thread类中的方法
释放cpu给其它线程 不释放锁资源
sleep(1000) 等待超过1s被唤醒
2.wait方法
属于Object类中的方法
释放cpu给其它线程,同时释放锁资源
wait(1000) 等待超过1s被唤醒
wait() 一直等待需要通过notify或者notifyAll进行唤醒
wait 方法必须配合 synchronized 一起使用
#### 锁释放时机代码演示 public static void main(String[] args) { Object o = new Object(); Thread thread = new Thread(() -> { synchronized (o) { System.out.println("新线程获取锁时间:" + LocalDateTime.now() + " 新线程名称:" + Thread.currentThread().getName()); try { //wait 释放cpu同时释放锁 o.wait(2000); //sleep 释放cpu不释放锁 //Thread.sleep(2000); System.out.println("新线程获取释放锁锁时间:" + LocalDateTime.now() + " 新线程名称:" + Thread.currentThread().getName()); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); thread.start(); try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } System.out.println("主线程获取锁时间:" + LocalDateTime.now() + " 主线程名称:" + Thread.currentThread().getName()); synchronized (o){ System.out.println("主线程获取释放锁锁时间:" + LocalDateTime.now() + " 主线程名称:" + Thread.currentThread().getName()); } }
🐓 ==和equals区别
1.==
如果比较的是基本数据类型,那么比较的是变量的值
如果比较的是引用数据类型,那么比较的是地址值(两个对象是否指向同一块内存)
2.equals
如果没重写equals方法比较的是两个对象的地址值
如果重写了equals方法后我们往往比较的是对象中的属性的内容
equals方法是从Object类中继承的,默认的实现就是使用==
🐓 String buffer和String builde
1.StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,
2.只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。
3.在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全而StringBuffer则每次都需要判断锁,效率相对更低
🐓 ArrarList和LinkedList区别
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
2.对于随机访问get和set,ArrayList效率优于LinkedList,因为LinkedList要移动指针。
3.对于新增和删除操作add和remove,LinkedList比较占优势,因为ArrayList要移动数据。 这一点要看实际情况的。若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。
🐓 HashMap底层
hashMap在1.8之前的底层结构是数组+链表,在1.8及以后使用的底层结构式数组+链表+红黑树
他们的区别还有put时的resize()方法的不同。
1.数组 Node<K,V>[] table ,哈希表,根据对象的key的hash值进行在数组里面是哪个节点
2.链表的作用是解决hash冲突,将hash值取模之后的对象存在一个链表放在hash值对应的槽位
3.红黑树 JDK8使用红黑树来替代超过8个节点的链表,主要是查询性能的提升,从原来的O(n)到O(logn)
4.通过hash碰撞,让HashMap不断产生碰撞,那么相同的key的位置的链表就会不断增长,当对这个Hashmap的相应位置进行查询的时候,就会循环遍历这个超级大的链表,性能就会下降,所以改用红黑树
🐓 HashMap和HashTable区别
1.线程安全性不同
HashMap是线程不安全的,HashTable是线程安全的,其中的方法是Synchronized,在多线程并发的情况下,可以直接使用HashTable,但是使用HashMap时必须自己增加同步处理
2.是否提供contains方法
HashMap只有containsValue和containsKey方法;HashTable有contains、containsKey和containsValue三个方法,其中contains和containsValue方法功能相同。
3.key和value是否允许null值
Hashtable中,key和value都不允许出现null值。HashMap中,null可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为null。
4.数组初始化和扩容机制
HashTable在不指定容量的情况下的默认容量为11,而HashMap为16,Hashtable不要求底层数组的容量一定要为2的整数次幂,而HashMap则要求一定为2的整数次幂,Hashtable扩容时,将容量变为原来的2倍加1,而HashMap扩容时,将容量变为原来的2倍。
🐓 线程的创建方式
1.继承Thread类创建线程
2.实现Runnable接口创建线程
3.使用Callable和Future创建线程 有返回值
4.使用线程池创建线程
#### 代码演示 import java.util.concurrent.*; public class threadTest{ public static void main(String[] args) throws ExecutionException, InterruptedException { //继承thread ThreadClass thread = new ThreadClass(); thread.start(); Thread.sleep(100); System.out.println("#####################"); //实现runnable RunnableClass runnable = new RunnableClass(); new Thread(runnable).start(); Thread.sleep(100); System.out.println("#####################"); //实现callable FutureTask futureTask = new FutureTask(new CallableClass()); futureTask.run(); System.out.println("callable返回值:" + futureTask.get()); Thread.sleep(100); System.out.println("#####################"); //线程池 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)); threadPoolExecutor.execute(thread); threadPoolExecutor.shutdown(); Thread.sleep(100); System.out.println("#####################"); //使用并发包Executors ExecutorService executorService = Executors.newFixedThreadPool(5); executorService.execute(thread); executorService.shutdown(); } } class ThreadClass extends Thread{ @Override public void run() { System.out.println("我是继承thread形式:" + Thread.currentThread().getName()); } } class RunnableClass implements Runnable{ @Override public void run(){ System.out.println("我是实现runnable接口:" + Thread.currentThread().getName()); } } class CallableClass implements Callable<String> { @Override public String call(){ System.out.println("我是实现callable接口:"); return "我是返回值,可以通过get方法获取"; } }
🐓 Java中有几种类型的流