1.多线程的实现有几种方式?实现步骤分别是怎样的?
有2种实现多线程的方式:
(1)继承Thread类,实现Thread类的run方法。随后在调用处建立子类的对象,并用子类的对象调用start方法,即可建立一条线程;
(2)实现Runnable接口,实现Runnable接口的run方法。随后在调用处建立实现类的对象,将对象传入Thread的有参构造方法中,建立Thread的
子类对象,并通过其调用start方法,至此也建立了一个线程。
2.继承Thread类和实现Runnable接口有啥区别?实现Runnable接口的优势体现在哪里?
继承Thread类后只需建立子类的对象,即可用其调用start方法,建立线程。而实现Runnable接口后需要先建立实现类的对象,再将其作为参数传入
Thread的有参构造方法中,建立Thread的子类对象,才能借助Thread的子类对象调用start方法,建立线程。
但是,继承Thread类后,该子类不能再继承其他父类,而实现Runnable接口则可以继承其他父类。此外,实现Runnable接口更符合“专人专事”的思想,
将功能实现和线程建立分开,有利于代码的维护与更新。
3.线程安全问题时怎么产生的?如何解决线程安全问题,有哪几种方式?
当多个线程共享一份数据,并试图对该数据进行修改时容易产生线程安全问题,即不同线程的执行顺序将产生不同的结果。
解决线程安全一般有三种方式:
(1)同步代码块,即将synchronized 关键字用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。格式:synchronized(同步锁){需要同步操作的代码},多个线程必须使用同一把同步锁。
(2)同步方法,即使用synchronized修饰的方法,保证A线程执行该方法的时候,其他线程只能在方法外等着。格式:public synchronized void method(){可能会产生线程安全问题的代码}。
(3)Lock锁,也称同步锁,将加锁与释放锁方法化了,用lock()方法加同步锁,用unlock()方法释放同步锁,在这两个方法之间的代码对线程具有排他性,即同一时间只允许一个线程
执行该段代码。
4.sleep()方法和wait()方法的区别?
sleep()方法:参数列表输入一个long值 ,表示毫秒值,代表程序在此处休眠指定毫秒后将自动恢复运行,在休眠期间,该线程将失去cpu的拥有权,但不会失去同步锁的拥有权。
wait()无参方法:程序运行到此处将进入无限睡眠,如果没有其他线程的notify方法唤醒就不会恢复运行。
wait()有参方法:数列表输入long值 ,表示毫秒值,代表程序在此处休眠指定毫秒后将自动恢复运行,在休眠期间,该线程将失去cpu和同步锁的拥有权,可以提前被notify唤醒。
|