创建线程的两个方式
-
定义一子个类继承 Thread 类
class Ticket extends Thread{} -
定义一个类实现 Runnable 接口
class Ticket implements Runnable{}
推荐使用第二种,那么第二种方式有什么好处呢?
- 实现接口的方式还可以继承其他类
- 实现接口方式 Runnable 负责任务, Thread 负责创建线程,将任务和线程的创建分开,降低耦合性
什么是线程安全问题?出现线程安全问题的条件是什么?
线程安全问题:多线程操作共享数据时,导致共享数据出错(具体案例在我的另一篇文章:https://blog.csdn.net/RookiexiaoMu_a/article/details/88623375
出现线程安全问题的条件:
- 有多个线程
- 有共享数据
- 有多条语句操作共享数据
tips:
在我的上一篇博客(就是上面的链接)中我们知道解决线程安全问题可以使用同步代码块、同步方法、和Lock锁。
其中同步方法、同步代码块涉及到一个同步锁的问题,那同步锁是谁?
对于非static方法,同步锁就是this。
对于static方法,同步锁就是当前方法所在类的字节码对象名(类名.class)
跟线程相关的一些方法
在 Object 类中有这样两个方法:
- void wait() 哪个线程执行 wait() 方法,这个线程就等待
- void notify() 唤醒正在等待的单个线程
tips:
wait和notify必须要在同步代码块中,使用锁对象调用
wait() 会释放锁,sleep() 不会
在这里估计小伙伴们会有这样一个疑问:
面试题:为什么wait()和notify()方法放在Object类中
答:wait()和notify()使用锁对象调用,而任何对象都可以作为锁,所以这两个方法就放在 Object 类中