Java程序的运行原理
- 当使用Java命令启动一个程序的时候,JVM启动。就启动了一个进程。
- main方法会执行。main方法的运行就是该进程中的一个线程(主线程)。也会启动GC,GC是后台线程(守护线程)。
package org.lanqiao.thread.demo;
public class ThreadDemo {
public static void main(String[] args) {
for(int i = 0 ; i < 1000000;i ++) {
new Demo();
}
for(int i = 0 ; i < 100000; i++) {
System.out.println("------------------主线程执行");
}
}
}
class Demo{
@Override
public void finalize() {
System.out.println("++++++++执行垃圾回收,资源释放.....");
}
}
创建线程
- 继承 Thread类 的类,是一个真正的线程类,可以直接创建其对象,该对象就是一个线程
- 实现 Runnanle接口 的类,并不是一个真正的线程类。使用的时候还是需要通过Thread的构造方法 Thread(Runnable target)
- 重写 run(); 将该线程要完成的事情写在run方法中,run方法不能直接调用,由线程来自动调用
- 启动线程:start(); 调用该方法来启动一个线程
多线程的实现方式
继承Thread
创建一个线程的步骤:
- 重写run方法:就是该线程所需要完成的工作
- 创建线程对象
- 调用start方法启动线程。线程会自动调用run方法
实现Runnable接口
- 重写run方法
- 创建Thread对象 ,将实现了Runnable接口的类作为Thread对象的一个成员
- 调用Thread类的run方法。
多线程两种实现方式的区别
继承的方式:
优点:因为继承了Thread类 ,直接就是一个线程类。可以直接使用线程的所有方法。
缺点:单继承
实现接口的方式:
优点:可以实现多个接口
缺点:不能直接创建线程类,需要借助Thread类来创建一个线程。编程稍显复杂。
package org.lanqiao.thread.demo;
public class ThreadDemo1 {
public static void main(String[] args) {
//创建线程对象
Thread1 t1 = new Thread1();
//启动线程
t1.start();
for(int i = 0 ; i < 1000 ; i ++) {
System.out.println("主线程运行");
}
}
}
class Thread1 extends Thread{
@Override
public void run() {
for(int i = 0 ; i < 1000; i++) {
System.out.println("新的线程执行");
}
}
}
package org.lanqiao.thread.demo;
public class ThreadDemo2 {
public static void main(String[] args) {
/*//创建一个线程对象
Thread t = new Thread(new Thread2());
//启动线程
t.start();*/
Thread2 t2 = new Thread2();
t2.run();
for(int i = 0 ; i < 1000 ; i++) {
System.out.println("-----主线程执行");
}
}
}
class Thread2 implements Runnable{
@Override
public void run() {
for(int i = 0 ; i < 1000 ;i++) {
System.out.println("+++自定义线程执行");
}
}
}