如何修复导致“不完整的启动数据包
369 2023-04-03 02:34:38
线程是程序的一条执行路径,Java允许一个程序有多条线程并发地执行。每条线程都有一个优先级,优先级更高的线程比优先级低的线程优先执行。每个线程都可以是守护线程或者非守护线程。创建线程实体时候,线程有一个初始化的优先级,守护线程要自己设置的。
当JVM启动的时候,就有一个非守护线程(通常是main线程),JVM一直执行,当它遇到下面的几种情况时候,就停止执行。
有两种方式去创建一个线程。一个是申明一个类,这个类要继承Thread类。这个子类应该重写Thread的run()方法,子类的实例可以分配和启动。
/* *Thread来创建线程 */public class extends MyThread{ public void run(){ System.out.println("继承Thread类,创建了一个线程"); } public static void main(String[] args){ MyTHread myThread = new MyThread(); myThread.start(); }}
另一个创建线程的方式是申明一个类,这个类实现了Runnable接口,然后实现run()方法。这个类的实例可以被分配,创建线程的时候作为参数来传递,然后就可以启动了。
/* *实现Runnable接口的方式创建线程 **/public MyRunnable implements Runnable{ publiuc void run(){ System.out.println("实现Runnable接口,创建了一个线程"); } public static void main(String[] args){ MyRunnable myRunnable = new MyRunnable(); new Thread(MyRunnable).start(); }}
一个类的实例被一个线程去执行,这个类可以去实现Runnable接口,这个类一定要定义一个无参的run()方法。
此接口是为希望在活动时执行代码的对象提供一个通用的协议。此外,Runnbale也提供一个方法,是类不需要子类化也能处于活动的状态。
确大多数的时候,我们都应该实现Runnable接口,而不是去继承Thread类。你要修改或者增强你的类的基本行为的时候,你才应该去继承,否则还是尽量使用接口实现。
实现Runnable接口的实体去创建线程的时候,启动一个线程会引起这个线程调用这个实体的run方法,这个run方法里面的逻辑就是你想去实现的业务。
构造方法的作用:开辟一个新的线程实体,这个实体有自己的目标执行实体、线程名字、所属线程组和栈大小。
public Thread(ThreadGroup group, Runnable target, String name, long stackSize) { init(group, target, name, stackSize);}
执行start()方法,就会创建一个线程,然后JVM就会调用这个线程的run()方法。调用start()方法,会导致两个线程并发地执行,一个是调用start()方法的线程,一个是新开的线程(这个线程调用的是run()方法)。
不能启动一个线程两次,一个线程没有执行完毕之前,不能重新启动。
start方法是一个同步的方法,首先要判断线程的状态不能为0,为0就抛出异常。然后将这个线程添加到线程组中,然后设置这个线程已经启动,然后调用start0()方法。public synchronized void start() { if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { } }}
如果这个线程是通过实现Runnable来构造的,就会调用Runnable接口的run()方法。继承Thread类的子类要重写这个run()方法。
public void run() { if (target != null) { target.run(); }}
我们主要看了Thread类的注释,和这个类的一些重要方法的使用场景和作用。看视频的时候总想着赶紧看完,这样会忽略了一些重要的知识点,当自己独自看源码的时候,会遇到很多自己无法独自理解的点,这时候就去查找资料,然后再加以理解。