1.什么是死锁
2.什么是Lock锁
/** * 第三种解决线程安全的方式 : Lock 锁 --> JDK5.0新增 * synchronized * 问题 : synchronized 与 lock 的异同? * 1.相同 : 两者都可以解决线程的安全问题 * 2.不同 : synchronized 在执行完相应的代码后 , 会自动释放锁 * lock需要手动上锁lock() , 代码执行完后 还需手动解锁 unlock(); */ class Window6 implements Runnable { private int ticket = 100; //1.实例化 ReentrantLock private ReentrantLock lock = new ReentrantLock(); //ReentrantLock()可以传参 , boolean : 默认为false 如果设为true ,则lock为公平锁 @Override public void run() { while (true) { try { //2.调用lock() --> 上锁 lock.lock(); if (ticket > 0) { System.out.println(Thread.currentThread().getName() + "卖票 , 票号为:" + ticket); ticket--; } else { break; } } finally { //3.调用unlock() --> 解锁 lock.unlock(); } } } } public class LockTest { public static void main(String[] args) { Window6 w = new Window6(); // 100号票被重复消费的问题 Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } }
3.线程间的通信
class Number implements Runnable{ private static int number = 0; @Override public void run() { while (true){ synchronized(this) { //notify() : 唤醒线程 notify(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } if (number <= 100) { System.out.println(Thread.currentThread().getName() + ":" + number); number++; } if(number>100){ break; } try { //调用wait()方式时线程进入阻塞状态 wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } public class CommunicationTest { public static void main(String[] args) { Number number = new Number(); Thread thread1 = new Thread(number); Thread thread2 = new Thread(number); thread1.setName("线程1"); thread2.setName("线程2"); thread1.start(); thread2.start(); } }
4. 面试题 : wait() 和 sleep() 的异同?
相同点 : 都可以使线程进入阻塞状态
不同点: ①.方法的调用方式不同 , sleep必须由Thread调用 , wait任何一个类都可以调 , 因为它声明在Object类中
②.调用场景不同 : sleep 可以随时随地调用 , wait必须在同步代码块或同步方法中调用
③.sleep进入阻塞状态后会保留锁 ,而 wait方法执行后 当前线程会释放锁
④.sleep必须等设置的时间到了以后才可以继续执行 , 而wait需要调用notify() 或 notifyAll()方法唤醒