一.集合与MAP
ArrayList<String> list = new ArrayList<String>();
//首先定义一个集合名字叫list
// 添加元素
list.add("你好");
// 插入元素
// add方法 - 当参数1添加下标时, 完成的是插入功能,否则将元素添加到集合的最尾端
list.add(0,"hello");
list.add(4,"WTF");
// 修改元素
// 参数1 - 下标
// 参数2 - 要修改的值
list.set(0,"hei!");
// 获取元素
String str = list.get(2);
// 删除元素
list.remove(1);
// 集合的元素个数
int size = list.size();
// 根据内容得到位置(下标) - 有相同元素时输出第一个
int index = list.indexOf("WTF");
// 根据内容得到位置,从最后一个开始找
int indexL = list.lastIndexOf("WTF");
// 子集
// subList(开始的位置 , 结束的位置);
// 将符合条件的区间(子集)返回到subL中
// 注意, 取得的子集包含"开始位置" , 但不包含"结束位置"(包含左端,不包含右端)
List<String> subL = list.subList(1,3);
// 移除元素 - 通过内容如果有重复元素,移除第一个
list.remove("WTF");
// 移除元素 - 通过内容
// 当删除成功,返回true
// 当删除失败,返回false
boolean ret = list.remove("WTF");
while (list.remove("WTF")){
}
// 判断是否包含某个元素
boolean ret = list.contains("WTF");
// 判断是否为空
boolean ret1 = list.isEmpty();
map是以字符串为下标的”无序数组”,key-value key是下标 ,value是值
HashMap<String, String> map = new HashMap<String, String>();
int i = 5;
String name = "name" + i;
map.put("name", "David");
map.put("age", "10");
map.put("level", "10");
map.put("phone", "10000");
//关于拆分字符串,通过使用split将字符串以”-“分割成数组,如果没有这个数组里就只有一个元素,也就是本身
String str = "1.hkjhlkj";
String[]a = str.split("-");
System.out.println(a[0]);
// 修改
// put方法 - 若key值不存在就添加
// 若key值存在就修改
map.put("level", "11");
// 获取值 - 注意,根据key而不是0,1等下标
String str = map.get("age");
// 删除
map.remove("name");
String str1 = map.get("sss");
// 判断是否包含
boolean ret = map.containsKey("age");
boolean ret1 = map.containsValue("10");
二.关于数据字典
1.字符串的拼接
String str1 = "abc";
String str2 = "def";
String ret3 = str1.concat(str2);
//不常用的拼接方法,此方法等效于ret
String ret = str1+str2;
字符串长度
String str1 = "picture.gif";
int len = str1.length();
//len就是字符串长度
替换某个字符串
String str = "picture.gif";
// 参数1 - 被替换的字符串
// 参数2 - 新字符串
// 注意, 将所有符合的字符都替换
String ret = str.replace("gif","jpg");
截取字符串
String str = "picture.gif";
// 注意, 包含开始位置, 但不包含结束位置
String ret = str.substring(0,7);
StringBuffer strB = new StringBuffer();
//拼接
strB.append("a");
strB.append("b");
// 删除
// 注意, 包含开始位置,不包含结束位置
strB.delete(0,1);
// 插入
// 参数1 - 位置
// 参数2 - 内容
strB.insert(1,"ccc");
2.关于随机数
int max = 100;
int min = 30;
int max1=0;
Random random = new Random();
int num = random.nextInt(max)%(max-min+1)+min;
return num;
3.同步锁中死锁的写法展示
private String s1 = "我是s1";
private String s2 = "我是s2";
public void p1(){
synchronized (s1){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("s1锁住了p1");
synchronized (s2){
for (int i = 0; i < 20 ; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("s2锁住了p1");
}
}
}
}
public void p2(){
synchronized (s2){
System.out.println("s2锁住了p2");
synchronized (s1){
for (int i = 0; i < 20 ; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("s1锁住了p2");
}
}
}
}
- 锁是一个对象
- 假如线程先访问这个del方法,那么锁对象就会被A线程持有
- 其他线程(B,C,D)想访问del方法的时候,会发现锁对象被A线程拿走了
- 那么(B,C,D)就都不能进入到del方法中
- 当A线程执行完del方法,会将锁对象释放出来
- 这时候(B,C,D)线程再争夺执行权
- 谁抢到了,谁来执行del方法
- 谁执行del方法,那么谁就又先行拿到了锁对象
- 这时候剩下的两个线程就又进不来del方法中了
- 使用synchronized关键字的两种方式;
- 1,在方法的声明上,使用synchronized关键字修饰
- 2,使用synchronized代码块将要执行的代码包起来
public synchronized void del1() {
for (int i = 0; i < 2500; i++) {
count -= 1;
System.out.println(Thread.currentThread().getName() + "----------------" + count);
}
}
public void del2() {
synchronized (this) {
for (int i = 0; i < 2500; i++) {
count -= 1;
System.out.println(Thread.currentThread().getName() + "----------------" + count);
}
}
}
- show方法,也是被synchronized关键字修饰的
- 而synchronized关键字修饰的方法的锁对象
- 就是该方法的调用者
- 对象.方法()
- 这里调用show方法,与调用del方法的对象是一个.所以show方法的锁对象
- 与del方法的锁对象也就是一个了
- 而第一个线程已经进入del方法
- 也就是持有了锁对象
- 第二个线程,要想进入show方法
- 需要等第一个线程从del方法中出来,释放锁对象的时候,才能进入show方法中
public synchronized void show(){
for (int i = 0; i < 2000; i++) {
System.out.println("****show****");
}
}
public void show1(){
synchronized (this){
for (int i = 0; i < 2000; i++) {
System.out.println("****show****");
}
}
}
- 建立线程的方式有两种
- 1,通过继承Thread类,创建一个Thread类的子类XXXThread
- 通过直接new XXXThread()的方式创建线程对象
- 2,通过实现Runnable接口的方式,创建可运行的类XXXRunnable
- 创建一个Thread类的对象,将XXXRunnable对象作为参数传入到new Thread(这里)的构造方法中
通过多线程调用死锁方法
private static void showDeadLock() {
PrinterDeadLock pdl = new PrinterDeadLock();
new Thread(new Runnable() {
@Override
public void run() {
pdl.p1();
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
pdl.p2();
}
}).start();
}
- 线程是抢占运行
- 谁抢到了CPU的执行权,那么谁就运行
在方法中直接创建多线程
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synDemo.del1();
}
});