一:线程和进程的区别?
进程:正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行中的程序,并且
具有一定的独立功能。
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中
是可以有多个线程的,这个应用程序也可以称为多线程程序。
简单来说:一个程序运行后至少有一个进程,一个进程中可以包含多个线程。
二:什么是线程?
线程是指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身。
三:怎么创建线程?
创建线程有两种方式:继承Thread类和实现Runnable接口。
1:继承Thread类
(1)Thread类介绍:从这个类中实例化的对象代表线程,程序员启动一个新线程需要建立Thread实例。
(2)Thread类中常用的两个构造方法
public Thread(String threadName) 和 public Thread()
(3)run()方法:run()方法中存放的是实现该线程功能的代码。run()的使用格式必须为:public void run(){ }
(4)start()方法:是执行线程。(调用run()方法)。如果不调用start()方法,线程永远不会启动,在主方法没用调用
start() 方法之前,Thread对象知识一个实例,而不是一个真正的线程。
(start()方法调用一个已经启动的线程,系统抛出IllegalThreadStateException异常。)
(5)代码:一个继承Thread类的方法创建线程。
public class a extends Thread{
private int count=10;
public static void main(String[] args){
new a().start();
}
public void run(){
while(true){
System.out.print(count+" ");
if(--count==0){
return;
}
}
}
}
在run()方法中使用的无限循环的形式是的线程一直运行下去,所以指定了一个跳出循环的条件。
运行结果:
代码二:创建两个线程。
public class a extends Thread{
a(){
super("Demo Thread");
System.out.println("Child threaad: "+this);
start();
}
@Override
public void run() {
try{
for(int i=5;i>0;i--){
System.out.println("Child Thread:"+i);
Thread.sleep(500);
}
}catch (InterruptedException e){
System.out.println("Chile interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ExtendThread {
public static void main(String[] args) {
new a();
try{
for(int i=5;i>0;i--){
System.out.println("Main Thread: "+i);
Thread.sleep(1000);
}
}catch(InterruptedException e){
System.out.println("Main thread interrupted.");
}
}
}
运行结果:
2:实现Runnable接口
(1)Java语言中不支持多继承,如果程序员需要继承其他的类(非Thread类)并使该程序可以使用线程,需要Runnable 接口。
(2)语法格式:public class Thread extends Object implenents Runnable
(3)实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。
两个构造方法:public Thread(Runnable r) 和 public Thread(Runnable threadOb,String threadName)
(4)使用Runnable接口启动新的线程的步骤如下
——(1)建立Runnable对象
——(2)使用参数与为Runnable对象的构造方法创建Thread实例
——(3)调用start()方法启动线程。
(5)
代码一:使用Runnable接口创建线程。
public class F implements Runnable{
public static void main(String[] args){
F f=new F();
Thread t=new Thread(f);
t.setName("线程一");
t.start();
F f1=new F();
Thread t1=new Thread(f1);
t1.setName("线程二");
t1.start();
}
public void run(){
for(int i=10;i>0;i--){
try {
Thread.currentThread().sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+": "+i);
}
}
}
代码二:使用Runnable接口创建两个线程。
public class a implements Runnable{
Thread t;
a(){
t=new Thread(this,"Demo Thread");
System.out.println("Child thread"+t);
t.start();
}
@Override
public void run() {
try{
for(int i=5;i>0;i--){
System.out.println("Child Thread:"+i);
Thread.sleep(500);
}
}catch (InterruptedException e){
System.out.println("Chile interrupted.");
}
System.out.println("Exiting child thread.");
}
}
public class ThreadDemo {
public static void main(String[] args) {
new a();
try{
for(int i=5;i>0;i--){
System.out.println("Main Thread:"+i);
Thread.sleep(1000);
}
}catch (InterruptedException e){
System.out.println("Main thread interrupted.");
}
System.out.println("Main thread exiting.");
}
}
运行结果:在多线程程序中主程序通常必须在最后结束运行,而上面的程序为了确保主程序在最后运行
,使主程序每次迭代之间休眠1000毫秒,而子线程只休眠500毫秒。这使得子线程结束比主线程终止的更早。
3:综上:run()和start()方法。
(1)启动线程是run()方法还是start()方法?
启动一个线程是调用start()方法,run()方法里面存放的是实现功能的代码,是线程启动后要进行回调的方法。
(2)使用哪种方法实现线程比较好?
使用Runnable接口的方式比较好。
原因:java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,使用Runnable接口更灵活。
四:停止线程(使用Thread.interrupt()方法)
而interrupted()测试当前线程是否已经是中断状态。
五:多线程分类
用户线程:
守护线程: (特点:用户线程结束,守护线程会随JVM一起结束工作)
最常见的守护线程:垃圾回收线程。
如何设置守护线程?使用Thread类中的setDaemon()方法设置当前线程为守护线程。