1.多线程的实现有几种方式?实现步骤分别是怎样的?
(1)继承Thread类
a.定义一个类继承Thread类
b.在类中重写run()方法
c.创建类的对象
d.调用start()方法,启动线程
(2)实现Runnable接口
a.定义一个类实现Runnable接口
b.在实现类中重写run()方法
c.创建实现类的对象
d.创建Thread类的对象,把实现对象作为构造方法的参数
e.调用start()方法,启动线程
JAVA语言是单继承,多实现,单独的一个类没有进行共性的抽取,只是重写方法,又不能做到资源共享,建议用实现。
2.继承Thread类和实现Runnable接口有啥区别?实现Runnable接口的优势体现在哪里?
区别;
(1)Runnable是一个是接口,Thread是该接口的一个子类。
(2)Thread不能做到资源共享,线程与线程之间相互独立,也就不会出现安全问题。实现Runnable接口可能会出现安全问题。
(3)继承Thread类可以不重写方法run方法,也可运行(没有意义),实现Runnable接口必须重写run方法。
优势:
(1)避免了Java单继承的局限性。
(2)适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想。
(3)把设置线程任务和开启新线程进行了分离,增加了扩展性,降低了耦合性。
3.线程安全问题时怎么产生的?如何解决线程安全问题,有哪几种方式?
线程安全的前提条件是:a.多线程环境 b.有共享数据c.有多条语句操作共享数据。多个线程同时进入到一个代码块,又一同去执行下面的非源子项的代码,造成线程安全问题。
由线程安全的条件,要想解决线程安全,只能对第三条进行操作,解决思路是只能有一个线程进入代码块,直到此线程从代码块出去,其他线程才能进入。
可以得到三种方法:
(1)同步代码块,synchronized(任意对象) { 多条语句操作共享数据的代码 } 就相当于给代码加锁了,任意对象就可以看成是一把锁,但是当线程很多时,效率会低。
(2.1)同步方法,就是把synchronized关键字加到方法上,格式是修饰符 synchronized 返回值类型 方法名(方法参数) { 方法体;}同步方法的锁对象是this。
(2.2)同步静态方法就是把synchronized关键字加到静态方法上,修饰符 static synchronized 返回值类型 方法名(方法参数) { 方法体; }同步静态方法的锁对象是什类名.class。
(3)Lock锁,lock()加同步锁,unlock() :释放同步锁。
4.sleep()方法和wait()方法的区别?
(1)wait()是放弃CPU的执行,无限等待,放弃锁对象,必须调用notify或者notifyAll方法才能唤醒。sleep()是此线程暂停执行指定时间,给其他线程执行机会,
但是依然保持着监控状态,过了指定时间会自动恢复,调用sleep()方法不会释放锁对象。
(2)sleep()必须要传入参数,wait()可以不传入参数,也可传入参数。
(3)作用范围,sleep()是一个静态的方法,可以在任何的地方使用,wait()只能在同步代码块或者同步方法中使用。
|