1.当两个或者更多隔线程互相持有对象想要的资源不放手,就会死锁
2.当同步代码快或同步方法中出现了嵌套使用
(1)同步代码快中,出现了另一个同步代码快,或调用了另一个同步方法
(2)同步方法中,出现了同步代码快,或者调用了另一个同步方法,而且两者之间有使用对象要的锁对象等资源时,就有可能出现死锁状态,尽量避免
如果出现了,要么手动停止,或者说我们要制造异常,让线程从死锁状态出来,然后再去抢夺资源。
(1)sleep方法在Thread类中声明,是静态方法,通过Thread类.sleep()调用
(2)wait方法在Object类中声明,是非静态方法,通过锁对象.wait() 调用
wait方法和notify为什么要在Object中声明“
因为wait方法必须是对象调用,但是锁对象是任意类型的对象
那么意味着任意类型的对象都必须具备wait方法,这样的方法只能放在根父类中声明
(2)sleep方法是必须制定时间,等待时间到了,或中途被interrupt了,就会自动醒来
wait方法,一种是指定时间,一种是无限时等待如果无限时等待必须notify唤醒之后才能继续
(3)当前线程遇到了sleep方法不会释放锁得,一直要等当前线程结束,才会释放锁
public class TestSleepWait { public static void main(String[] args) { MyThread m1 = new MyThread(); MyThread m2 = new MyThread(); m1.start(); m2.start(); } } class MyThread extends Thread{ private int num = 1; public void run(){ synchronized (MyThread.class) { System.out.println(num++); /* try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); }*/ try { MyThread.class.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } }(1)public static double sqrt(double a):求x的平方根
(2)public static double random)(): 返回带正号的double 值,大于等于0.0且小于1.0
(3)public static double pow (double a, double b):返回第一个参数的第二个参数次幂,即a的b次方
(4)public static double abs (double a ) 返回绝对值
(5)public static double max(double a, double b):求a和b的最大值
(6)public static double min(double a, double b):求a和b的最小值
(7)public static double floor (double a);向下取整
public static double ceil (double a);向上取整
public static long round (double a);四舍五入取整(最接近的整数)
-x.5比较特殊
java.math,BigDecimal:定点小数和大的小数,可以精确到小数点后n位,如果可以整除,可以用该方法,如果不能整除,说明保留小数点后多少位
float 和double :浮点数,不精确.
java.math.BigInerger:表示大整数
用法 BigInteger ig1 =new Big Integer(参数);
可以产生随机的整数、小数、boolean等所有数据类型
Math.random只能产生【0,1】之间的随机小数
Random random = new Random();
第一代:java.util.Date等
第二代:java.util.Calendar等
第三代:java.time包及其子包的类型
(1)Date() 获取当前系统时间
(2)Date(long time),根据指定的毫秒值,获取对应的日期时间
(2)Long getTime()获取当前系统时间距离1970-1-1凌晨的毫秒值
等同于 System.currentTimeMillis()
问题:为什么开始于1970年
Unix操作系统在1970年设计数来,把1970-1-1凌晨作为计算机时间的原始起点
Date类型大部分都是已过时的方法
他是一个抽象类,
如何创建对象:
(1)创建它子类对象
(2)在Calendar类中提供静态方法
Date和Calendar:
(1)使用麻烦
无法获取满足本地人阅读习惯的日期时间对象
需要借助DateFormat,它是抽象类,他有一非常
(2)可变对象:在开发中,日期对象,某个对象某个瞬间的日期时间,是不应该变的
(3)没有考虑闰秒
(1)本地的日期类型的API
LocalDate:日期、
Localtime:时间
LocalDateTime:日期和时间
LocalDateTime.now()方法指当前时间
LocalDateTime.of()方法可以指定时间
.isLeapYear():判断指定时间是不是闰年
修改日期或时间对象会返回一个新的对象结果,必须接受
(1)System.out 对象
(2)System.in 对象
(3)public static long currenTimeMillis():获取距离1970年的时间
(4)public static void arraycopy(Object src,int srcPos,Object,destPos,int length)
src:原数组
srcPos:原数组的起始位置
dest:目标数组
destPos:目标数组的起始位置
length:要挪动的元素的长度
total个元素, arr.length长度 假设length = 10, total = 7, 元素的下标[0,6] i=2 移动[3],[4],[5],[6] 删除arr数组的[i] 元素: System.arraycopy(arr, i+1, arr, i, total-i-1) i=2 移动[2],[3],[4],[5],[6] 插入arr数组的[i]元素: System.arraycopy(arr, i, arr, i+1, total-i)
(5)public static void gc():通知GC工作,进行垃圾回收,通知后,不代表GC线程立刻工作。 (6)public static void exit(int status):终止当前运行的Java虚拟机。 该参数作为状态代码; 按照惯例,非零状态码表示异常终止。 (7)public static Properties getProperties():获取所有的系统数属性
runtime.getRrntime()代表JVM的运行环境
方案一:
先新建一个数组,然后把元素按照反转之后的正确的顺序放进去,指向新的数组
缺点:浪费空间
方案二:
首尾交换
public class TestArray { @Test public void test01(){ int[] arr = {1,2,3,4,5}; //反转之后:arr中{5,4,3,2,1} //方案一:先新建一个数组,然后把元素按照反转之后的正确的顺序放到新数组中,让arr指向新数组 int[] newArr = new int[arr.length]; //把arr中的元素逆序放到newArr for (int i = 0; i < newArr.length; i++) { /*newArr[0] = arr[arr.length-1]; newArr[1] = arr[arr.length-2];*/ newArr[i] = arr[arr.length-1-i]; } //让arr指向新的数组 arr = newArr; //遍历 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } @Test public void test02(){ int[] arr = {1,2,3,4,5}; //首尾交换 /* 1 2 3 4 5 1和5换 2和4换 5个元素换2次 10个元素:5次 交换的次数 = 数组的长度/2(整数与整数相除只保留整数部分) */ //循环的次数 = 交换的次数 for (int i = 0; i < arr.length/2; i++) { //交换的过程 int temp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = temp; } //遍历 for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } }之前:数组的查找,是顺序查找,从[0]开始,挨个比较是否目标对象,如果是,找到了,如果不是,一直找到最后 现在:二分查找,又称为折半查找 二分查找有要求,数组必须是有序的
public class TestArray5 { @Test public void test01(){ int[] arr = {2,5,7,8,10,15,18,20,22,25,28};//数组是有序的 int value = 18; //查找value是否在arr中,如果在,打印下标,如果不在,说明不在 int left = 0; int right = arr.length-1; int mid = (left +right)/2; int index = -1; while(left <= right){ if(arr[mid] == value){ index = mid; break; }else if(value > arr[mid]){ left = mid +1; }else{ right = mid - 1; } mid = (left + right) / 2; } if(index==-1){ System.out.println("没找到"); }else{ System.out.println("找到了,下标是:" + index); } } }java.util.Arrays工具类:此类包含用来操作数组(比如排序和搜索)的各种方法。 开发中:能够用API的方法,肯定是最简洁的, 面试中,需要知道底层是如何实现的,甚至有些算法要手动会实现。
System.arraycopy这个方法和数组关系,为啥在System类中,不在Arrays类? 因为版本的问题。JDK1.0时候,还没有Arrays工具类,但是arraycopy这个方法已经在使用了, 当时没地方放这个方法,只好放在系统类中。后期所有和数组有关的方法都在Arrays类中。
(1)public static int binarySearch(int[] a, int key):二分查找 如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点 被定义为将键插入数组的那一点: 它有很多重载形式,形参的类型不同
(2)public static int[] copyOf(int[] original,int newLength):复制数组 它有很多重载形式,形参的类型不同
(3)public static int[] copyOfRange(int[] original,int from, int to) 它有很多重载形式,形参的类型不同
(4)public static boolean equals(int[] a, int[] a2):比较两个数组是否相同 它有很多重载形式,形参的类型不同
(5)public static void fill(int[] a,int val):用val填充整个数组 它有很多重载形式,形参的类型不同
(6)public static void sort(int[] a) :对指定的 int 型数组按数字升序进行排序。该排序算法是一个经过调优的快速排序法 它有很多重载形式,形参的类型不同
(7)public static void sort(Object[] a):给对象数组排序,按升序排列,要求元素必须是java.lang.Comparable public static void sort(Object[] a, Comparator c):按升序排列,需要一个Comparator实现类对象
(8)public static String toString(int[] a) 它有很多重载形式,形参的类型不同