1,什么是进程,什么是线程?
进程是正在进行中应用的程序,是程序在计算机上的一次执行活动,其实就是该应用程序在内存中分配的空间。
进程与线程的区别(转自http://www.cnblogs.com/hazir/archive/2011/05/09/2447287.html)
-
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
-
线程是进程的一个实体, 是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源。
-
一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序 健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
2,用文字体现你对jvm启动时的多线程理解?(知道 fianlize 的作用)
fianlize是用于垃圾回收机制中,对垃圾对象进行回收。
protected void finalize() throws Throwable
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写finalize方法,以配置系统资源或执行其他清除。System.gc()//调用垃圾回收器
3,创建线程的两种方式?和区别?用售票例子体现第二种方式。★★★★★
第一种是继承Thread()类,并复习run方法(假设class Demo extends Thread)
Demo d = new Demo();//创建线程对象
d.start();//开启线程
第二种是实现 Runnable 接口1.实现Runnable接口(假设class Demo implements Runnable)
2.覆盖run方法
3.通过Thread类创建线程对象
4.将runnable接口的子类对象作为实参传递给Thread类中的构造方法
5.调用start方法开启线程,并运行runnable接口子类的方法
Demo d = new Demo();
Thread t = new Thread(d);
d.strat();
区别:1,Runnable接口解决了单继承的局限性;
2,Runnable接口的出现将线程对象和线程任务进行了分离,使其更程序更符合面向对象的特性。
4,调用 start 方法和 run 方法区别?★★★★★
start(): 开启线程的同时,调用 run() 方法!
run(): 知识在调用 run 方法,没有开启线程!
5,线程状态的内容和每一个状态的特点?
6,什么时候使用多线程?
需要多代码同时运行时。
7,线程安全问题表现?原因?解决思想?解决具体的体现?★★★★★
原因:1.多个线程在同时处理共享数据
2.线程任务中有多条代码在操作共享数据
解决思想:在某一时刻只能有一个线程在处理共享数据的多条语句。
解决体现:Java中提供了同步代码块和同步函数对引起安全的代码进行封装
8,同步的好处,弊端,前提?
好处:解决了健壮性问题
弊端:1,降低了效率
2,容易引发死锁。
前提:必须要有多个线程存在于同一个线程(同一把锁)中。9,并发访问单例懒汉式是否有问题?怎么解决?★★★★★
有问题,会有线程安全问题。解决办法是加锁同步。即保证效率又保障健壮性的代码如下:
private static Single s = null;
Single(){}
public static Single getInstance(){
if(s==null){
synchronized (Single.class) {
if(s==null){
s = new Single();
}
}
}
return s;
}
10,死锁的原理,以及死锁的代码示例?★★★★★
原理:锁出现了嵌套情况,导致锁程序的无法运行,程序在不断的判断锁。
代码体现如下:
public class Ticket6 implements Runnable {
private int num = 100;
boolean flag = true;
public void run() {
System.out.println(flag);
if (flag) {
while (true) {
synchronized (Ticket6.class) {
sale();
}
}
}
// !!!!重点注意:
// if(flag){while(true)}的效果与while(flag)作用不同,当flag的
// 值改为false之后,原在true中的线程进行判断,则会出循环,导致线程进入
// false循环(当true判断在false之前时),两个线程都会依次执行false循
// 环中的操作,有同步,但没了死锁的可能,并且会处于无线循环。
// this->ticket.class
else {
while (true) {
System.out.println("false");
this.sale();
}
}
}
public synchronized void sale() {
// TODO Auto-generated method stub
synchronized (Ticket6.class) {
if (num > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
System.out.println(num-- + "**sale**" + Thread.currentThread().getName());
}
}
}
}