java_多线程 (三)

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()方法唤醒

posted @ 2021-01-27 17:30  Anonymity_Zhang  阅读(33)  评论(0编辑  收藏  举报