Q:什么是线程?什么是进程?
A:进程是程序在某个数据集合上的一次活动,线程则是进程中的最小执行单元,进程是需要分配系统资源的,但是线程不必,它只是需要一点在运行中必不可少的资源就可以,支持与同一个进程下的所有线程共享资源.
Q:为什么要创建线程?
A:由于进程切换时需要消耗系统资源大,效率慢,所以我们就需要创建线程.因为线程是CPU调度和分派的基本单位,创建线程可以提高CPU的利用率,给系统操作减轻负担.
Q:线程与进程的区别是什么?
A:1.进程是需要分配系统资源的,线程只会在运行时占用一些CPU空间.一个进程崩溃了,不会影响其他进程的运行,但是一个线程崩溃了,整个进程挂掉,这是因为线程没有独立的内存空间,同一个进程中的线程共享同样的虚拟内存空间,一旦有一个线程写坏了其中一个指针,其他线程同样崩溃.
2.进程中必须有一个线程,线程是不可以单独存在的,必须在进程中运行.
3.进程中可以有多个线程同时执行多个任务,实现资源共享.同时系统并没有将多个线程看成多个应用,来进行进程的资源分配和调度.
Q:线程的创建方式:
1.继承Thread类,重写run方法(也可以不重写)
2.实现Runnable接口,重写run方法
3.实现Callable接口和使用FutrueTask创建线程
4.利用内部类的方法创建线程
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class ThreadTest {
public static void main(String[] args) {
// Thread1 thread1 = new Thread1();
// thread1.start();
// new Thread(new Thread2()).start();
// Thread3 thread3 = new Thread3();
// FutureTask<Integer> threadTask = new FutureTask<Integer>(thread3);
// new Thread(threadTask, "有返回值的线程").start();
// new Thread(new Thread() {
// public void run() {
// try {
// Thread.sleep(1000);
// System.out.println(Thread.currentThread().getName());
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// }, "匿名内部类创建线程4").start();
//
// new Thread(new Runnable() {
//
// public void run() {
// try {
//
// Thread.sleep(1000);
// System.out.println(Thread.currentThread().getName());
// } catch (Exception e) {
// e.printStackTrace();
// }
//
// }
// }, "匿名内部类创建线程5").start();
new Thread(new Thread("thread6"){
public void run() {
try {
System.out.println(getName());
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}, "匿名内部类创建线程6").start();
}
}
//继承Thread类
class Thread1 extends Thread{
public void run() {
for(int i = 0; i < 10; i ++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//实现Runnable接口
class Thread2 implements Runnable{
public void run() {
for(int i = 0; i < 10; i ++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + i);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//利用Callable接口和FutrueTask创建有返回值的线程
class Thread3 implements Callable<Integer> {
public Integer call() throws Exception {
int i = 0;
for(; i < 10; i ++) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + i);
} catch (Exception e) {
e.printStackTrace();
}
}
return i;
}
}
Q:线程的生命周期?
A:线程的生命周期分为五个阶段,分别是创建,可运行,运行,阻塞和死亡阶段.
创建阶段:实现Runnable接口或者实现Callable接口和FutureTask方法或者继承Thread类,创建其实例对象就进入创建阶段.
可运行:可运行阶段分为三种情况:1.线程对象实例调用start()方法,该线程就进入可运行阶段;2.线程调用yield()方法,让出cpu,当前进入可运行阶段;3.线程获取对象锁之后进入可运行状态.
运行:当前线程所处的阶段就是运行阶段,可运行阶段和运行阶段是可以相互转换.
阻塞阶段:阻塞阶段也是分为四种情况:1.当前线程调用sleep()方法,线程进入阻塞阶段;2.当前线程调用wait()方法,线程进入阻塞状态;3:运行在当前线程的其他线程调用join()方法,当前线程会进入阻塞状态;4.当前线程处于用户输入阶段,线程进入阻塞状态.当前状态的线程如果调用
死亡阶段:当线程的run方法或者主线程的main方法执行完毕或者该线程抛出未捕获的exception或者error,该线程就死亡了.线程一旦死亡,就不可以再次复活,调用start()方法会抛出异常IIIegalThreadStateException.因此判断线程是否死亡,我们可以调用isAlive方法,true说明其处于就绪,运行,阻塞三种状态,false处于创建或死亡状态.