一. Java基础-死锁
-
定义:当两个线程相互等待对方释放同步监视器就会发生死锁
-
具体实例:
class A{
public synchronized void foo(B b) {
//1
System.out.println(“当前线程名:” + Thread.currentThread().getName() + “进入了A实例的foo()方法”);
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}//2 System.out.println("当前线程名:" + Thread.currentThread().getName() + "企图调用B实例的last()方法"); b.last(); } public synchronized void last(){ System.out.println("进入了A类的last()方法内部"); }
}
class B{
public synchronized void bar(A a) {
//3
System.out.println(“当前线程名:” + Thread.currentThread().getName() + “进入了A实例的bar()方法”);
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}//4 System.out.println("当前线程名:" + Thread.currentThread().getName() + "企图调用A实例的last()方法"); a.last(); } public synchronized void last(){ System.out.println("进入了B类的last()方法内部"); }
}
public class DeadLock implements Runnable{
A a = new A();
B b = new B();public void init(){ Thread.currentThread().setName("主线程"); a.foo(b); System.out.println("进入了主线程之后"); } public void run(){ Thread.currentThread().setName("副线程"); b.bar(a); System.out.println("进入了副线程以后"); } public static void main(String[] args) { DeadLock d1 = new DeadLock(); new Thread(d1).start(); d1.init(); }
}
//先执行1处,对A对象加锁—》主线程睡眠0.2毫秒—》开始执行副线程3处,对B对象加锁—》副线程睡眠0.2毫秒—》主线程苏醒,
//执行3处,希望对B对象加锁,但是此时副线程对B对象的锁并没有释放,导致主线程阻塞—》副线程苏醒,执行4处,希望对A对象加锁,
//但是此时主线程对A对象的锁并没有释放,导致副线程阻塞—》两个线程相互等待对方释放同步监视器—》造成“死锁”
二. 数据结构-树
题目1:
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
算法实现思路:
利用LinkedList的双队列的性质,对树的每层进行遍历
算法实现代码:
public class PrintTree {
public ArrayList<ArrayList<Integer>> printTree(TreeNode pRoot) {
//res用来存每一层的输出
ArrayList<ArrayList<Integer>> res = new ArrayList<>();
//异常case
if (pRoot == null)
return res;
//正常case
LinkedList<TreeNode> queue = new LinkedList<>();
queue.push(pRoot);
while (!queue.isEmpty()) {
ArrayList<Integer> list = new ArrayList<>();
int size = queue.size();
// for (int i = 0; i < size; i++) {
// TreeNode node = queue.poll();
// list.add(node.val);
// if (node.right != null) {
// queue.addLast(node.left);
// }
// if (node.left != null) {
// queue.addLast(node.right);
// }
// }
// if (!list.isEmpty()) {
// res.add(list);
// }
for (int i = 0; i < size; i++) {
//peek()获取队列的头元素,但是不删除该元素
if (queue.peek().left != null) {
queue.add(queue.peek().left);
}
if (queue.peek().right != null) {
queue.add(queue.peek().right);
}
//poll()获取队列的头元素,删除该元素
list.add(queue.poll().val);
}
res.add(list);
}
return res;
}
//测试脚本
public static void main(String[] args) {
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(4);
root.right.left = new TreeNode(5);
PrintTree p = new PrintTree();
System.out.println(p.printTree(root));
}
}