
转载地址:原文
一:简述
Java并发与多线程专栏的第一篇文章,主要介绍java多线程的一些基础知识。
二:java的线程状态
public enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
}
java线程有六种状态
1.NEW: 新生状态,线程创建了,但是没有调用start()方法,就处于这种状态
2.RUNNABLE: 可运行状态 线程调用start()方法进入该状态 该状态下可以被cpu调度
3.BLOCKED 阻塞状态,线程被synchronized锁阻塞进入该状态
4.WAITING 等待状态,线程调用wait(),join(),LockSupport.park()方法会进入该状态
5.TIMED_WAITING 有时间限制的等待状态,线程调用了 wait(timeout),sleep(timeout), join(timeout),LockSupport.parkNanos(timeout),LockSupport.parkUntil()等方法会进入该状态
6.TERMINATED 结束状态,调用stop(),destroy()等方法(因为不安全,在java8中已经删除)或者线程run()方法执行完成会进入该状态。
三: 线程的创建
1.实现Runnable 实现run()方法
public class TestThread implements Runnable {
@Override
public void run() {
System.out.println("java多线程");
}
public static void main(String[] args) {
Thread thread = new Thread(new TestThread());
thread.start();
}
}
2.继承Thread类 重写run()方法
public class TestThread extends Thread {
@Override
public void run() {
System.out.println("java多线程");
}
public static void main(String[] args) {
TestThread thread = new TestThread();
thread.start();
}
}
3.实现Callable,实现call()方法
public class TestThread implements Callable {
@Override
public Object call() throws Exception {
System.out.println("java多线程");
return null;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask futureTask = new FutureTask<>(new TestThread());
futureTask.run();
//阻塞获取线程的执行结果
Object o = futureTask.get();
}
}
四:线程的停止和中断
线程的停止
线程停止的方法有两种
方法一:调用stop(),destroy()等方法,直接强制停止线程,这种方式存在严重的安全问题,所以不推荐使用 并且在java8中已经被删除。
方法二:run()方法执行完成
public class TestThread implements Runnable {
//通过一个volatile变量来控制线程的停止
private static volatile boolean flag = false;
@Override
public void run(){
while(!flag){
System.out.println("java多线程");
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TestThread());
t.start();
Thread.sleep(50);
flag = true;
}
}
线程的中断
在java虚拟机中每个线程都有一个interrupt标识,表示线程是否中断,当线程处于WAITING或者TIMED_WAITING状态被中断的时候会抛出InterruptedException。java为中断提供了一些api,通过interrupt()方法中断线程,isInterrupted()方法可以知道线程是否被中断。
而中断标志也可以用来停止线程。
public class TestThread implements Runnable {
@Override
public void run(){
//可以通过修改中断标志来停止线程
while(!Thread.currentThread().isInterrupted()){
System.out.println("java多线程");
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TestThread());
t.start();
Thread.sleep(500);
//修改中断标志为true
t.interrupt();
}
}
结果如下:
当线程处于WAITING或者TIMED_WAITING状态被中断的时候会抛出InterruptedException
结果如下:
可以看到我们调用了interrupt()方法,线程并没有停止,这是因为InterruptedException会将interrupt重置 也就是恢复成false,这是因为现在在处于WAITING或者TIMED_WAITING状态时,这时候被中断 应该交给被中断的线程自己决定是否要中断。
不需要中断的时候可以不做处理 如果我们需要中断的时候可以在处理异常的时候再次调用interrupt()方法。
代码如下:
public class TestThread implements Runnable {
private static volatile boolean flag = false;
@Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
//TODO 在中断前我们还可以做一些 *** 作 比如关闭资源 保存数据等 *** 作
//确定要中断线程 调用interrupt()方法
Thread.currentThread().interrupt();
e.printStackTrace();
}
System.out.println("java多线程");
}
}
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new TestThread());
t.start();
Thread.sleep(500);
t.interrupt();
}
结果如下:
可以看出线程已经停止。
五 结束语
原文链接:原文
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)