Java——多线程
一、创建线程有三种方式
1.继承 Thread类,重写 run ()方法
2.实现 Runnable 接口,重写run()方法
3.实现 Callable 接口,重写call()方法,在new Callable接口实现的对象线程后,传入到新new的一个FutureTask对象里
二、sleep() 和 wait() 的区别
1.类的不同:sleep() 来自 Thread,wait() 来自 Object。
2.释放锁:sleep() 不释放锁;wait() 释放锁。
3.用法不同:sleep() 时间到会自动恢复;wait() 可以使用 notify()/notifyAll()直接唤醒。
三、notify()和 notifyAll()的区别
notifyAll()会唤醒所有的线程,notify()之后唤醒一个线程。notifyAll() 调用后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执行,如果不成功则留在锁池等待锁被释放后再次参与竞争。而 notify()只会唤醒一个线程,具体唤醒哪一个线程由虚拟机控制。
四、线程的 run() 和 start() 的区别
start() 方法用于启动线程,run() 方法用于执行当前线程的代码。run() 可以重复调用,而 start() 只能调用一次。
五、多线程的运行安全
1.使用安全类,比如 Java. util. concurrent 下的类。
2.使用自动锁 synchronized,可以给类、方法、代码块加锁。
3.使用手动锁 Lock,而 lock 只能给代码块加锁。
4.通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。
5.死锁:当线程 A 持有独占锁a,并尝试去获取独占锁 b 的同时,线程 B 持有独占锁 b,并尝试获取独占锁 a 的情况下,就会发生 AB 两个线程由于互相持有对方需要的锁,发生的阻塞现象。