1.多线程的实现有几种方式?实现步骤分别是怎样的?
多线程的实现有两种方式:
第一种:继承Thread类
①继承Thread类,重写该类的run()方法,run()方法写的是线程所要完成的任务
②测试类中创建Thread子类的实例对象,也就是创建线程对象
③调用该线程对象的start()方法来启动该线程
第二种:实现Runnable接口
①创建Runnable接口的实现类,重写Runnable接口的run()方法,设置线程任务
②创建Runnable接口的实现类对象,并将该对象作为Thread的target来创建Thread对象
③调用Thread对象的start()方法,开启新线程
2.继承Thread类和实现Runnable接口有啥区别?实现Runnable接口的优势体现在哪里?
继承Thread类和实现Runnable接口的区别:
①继承Thread类将设置线程任务和开启新线程合在一起,代码耦合度较高,而且不适合数据共享
②实现Runnable接口把设置线程任务和开启新线程进行分离,降低耦合度,且适合资源共享
实现Runnable接口比继承Thread类所具有的优势:
①避免了Java单继承的局限性,一个类继承了Thread类就不能继承其它类,而实现Runnable接口还可以实现其它的接口,继承其它类
②实现Runnable接口的方式,把重写run()方法设置线程任务和调用start()方法开启新线程进行了分离,降低了代码耦合度,增强了程序的健壮性
③适合多个相同的程序代码的线程去共享同一个资源
3.线程安全问题时怎么产生的?如何解决线程安全问题,有哪几种方式?
线程安全问题产生原因:
当程序中有多个线程访问共享数据时,且多个线程中对该数据有写操作时,容易出现线程安全问题
解决线程安全问题有三种方式:
第一种:同步代码块
使用 synchronized 关键字,用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问
格式:
synchronized(同步锁){
需要同步操作的代码
}
其中,同步锁的作用是把同步代码块锁住,只让一个线程在同步代码块中执行,可以是可以使用任意的对象,但是必须保证多个线程使用的锁对象是同一个
第二种:同步方法
把访问了共享数据的代码抽取出来,放到一个方法中,在方法上添加synchronized修饰符
格式:
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码(访问了共享数据的代码)
}
同步方法的锁对象是this,静态同步方法的锁对象是方法所在类的字节码对象(类名.class)
第三种:Lock锁
a.在成员位置创建一个ReentrantLock对象
b.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
c.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
4.sleep()方法和wait()方法的区别?
sleep()方法和wait()方法的区别:
①wait()方法是来源于Object类的方法,sleep()方法是来源于Thread类的方法
②wait()方法调用之后,会释放锁对象和CPU执行权;sleep()方法只释放CPU执行权,不释放锁对象
|