小编给大家分享一下Java线程如何定义,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
定义线程
定义一个实现 Runnable 接口的类 A, 并实现该接口中的 run 方法, 最后实例化类 A, 作为 Thread 类的构造参数。
// 定义一个实现 Runnable 接口的类 A, 并实现该接口中的 run 方法
public class A implements Runnable {
[@Override](https://my.oschina.net/u/1162528)
public void run() {
System.out.println("开启一个县城... ");
}
}
// 实例化类 A
A task = new A();
// 作为 Thread 类的构造参数。
Thread t = new Thread(task);
定义一个继承 Thread 类的类 A, 并重写类 A 的 run 方法
注意: 其实还是 Runnable 接口中 run 方法,因为 Thread 类实现了 Runnable接口
// 定义一个继承 Thread 类的类 A, 重写类 A 的 run 方法
public class A extends Thread {
[@Override](https://my.oschina.net/u/1162528)
public void run() {
System.out.println();
}
}
Thread t = new Thread();
其他:通过线程池 或者 实现Callable接口的方法。 暂时不多做介绍
通过实现 Runnable 接口与继承 Thread 类定义线程的区别
Runnbale 接口的实现类必须重写 run() 方法, 而 Thread类 的实现类有默认实现的run方法
Runnbale 接口的实现类并不是真正的线程类, 他只是执行线程的一个任务类
Thread 类要想以线程的方式执行run方法,只能依靠Thread类
继承 Thread 类会造成单继承的局限性
线程的生命周期
线程的生命周期指的是从线程的创建到启动直到结束。
java 线程的 6 种状态
注意: 这里说的是 java 线程的状态,并非操作系统的线程状态
Thread 类中通过枚举定义了线程的状态
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
New:new Thread() 后线程的状态就是新建。
Runnable:线程一旦调用 start() 方法,无论是否运行,状态都为 Runable, Runable 状态指示表示线程可以运行,不表示线程当下一定在运行,线程是否运行由虚拟机所在操作系统调度决定。
BLOCKED:线程试图获取一个内部对象的 Monitor(进入synchronized方法或synchronized块)但是其他线程已经抢先获取,那此线程被阻塞,知道其他线程释放 Monitor 并且线程调度器允许当前线程获取到 Monitor,此线程就恢复到可运行状态。
WAITING:当一个线程等待另一个线程通知调度器一个条件时,线程进入等待状态。
TIMED_WAITING:和等待类似,某些造成等待的方法会允许传入超时参数,这类方法会造成计时等待,收到其他线程的通知或者超时都会恢复到可运行状态。
TERMINATED:线程执行完毕正常结束或执行过程中因未捕获异常意外终止都会是线程进入被终止状态
扩展
操作系统中线程的5中状态
线程调度
操作系统会给每个线程分配时间片, 在某一时刻只执行一个时间片的线程。每个java程序启动后, jvm会自动帮我们创建两个线程, 一个是main, 一个是GC
线程调度的实现方式
java 线程分类
用户线程
也称非守护线程, jvm会在所有非守护线程结束后随之离开
守护线程
也称作后台线程, 当进程中的所有 非后台线程 结束后, 后台线程也会随之结束。
线程安全问题
出现线程不安全的条件
必须存在两个或者两个以上的线程。
多个线程共享着一个资源,而且操作资源的代码有多句。
解决办法
1. 同步代码块
使用 synchronized 修饰代码块, 如下所示
public void methodA() {
synchronized (this){
// doSomething
}
}
注意的事项:
2. 同步函数
使用synchronized修饰该函数则称作为同步函数, 如下所示。
public synchronized void methodA() {
// doSomething
}
注意的事项:
推荐使用: 同步代码块
同步代码块的锁对象可以由我们自己指定,同步函数的锁对象是固定的。
同步代码块可以随意指定那个范围需要被同步,而同步函数必须是整个函数都同步, 代码不灵活。
死锁
死锁出现的条件
必须存在两个及两个以上的线程
这些线程共享两个及两个以上的资源
多线程各自持有不同的锁,并试图获取对方已持有的锁
如何解决
以上是“Java线程如何定义”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注天达云行业资讯频道!