多线程
2019-12-31 本文已影响0人
全麦土司
概念识别
并行VS并发
1、并行:并发是指同一时刻处理事情的能力。
2、并发:在单位时间内处理事情的能力。
进程VS线程:
进程:计算机运行资源分配的最小单位,进程内部有多个线程,会共享这个进程的资源。
线程:CPU进行调度的最小单位。依赖进程存在。
java是协作式,而不是抢占式
启动线程的三种方式:
- 继承Thread类
- 实现Runnable接口
- 实现callable<V>接口,这个方式可以通过FutrueTask类型的get()方法返回结果。
/*
如何开启线程
*/
public class NewThread {
/*
方式一:继承Thread接口
*/
private static class ThreadA extends Thread {
@Override
public void run() {
System.out.println("extends Thread~~~");
}
}
/*
实现了runnable 接口
*/
private static class ThreadB implements Runnable {
@Override
public void run() {
System.out.println("implements Runnable~~~"+Thread.currentThread().getId());
}
}
/*
实现了callable接口
*/
private static class ThreadC implements Callable<String>{
/*
这里的返回值是根据传入的参数类型而改变的。
*/
@Override
public String call() throws Exception {
return "implements Callable<String>";
}
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ThreadA threadA = new ThreadA();
threadA.start();
ThreadB threadB = new ThreadB();
new Thread(threadB).start();
/*
执行callable接口的实现类
*/
ThreadC threadC = new ThreadC();
FutureTask<String> futureTask = new FutureTask<>(threadC);
new Thread(futureTask).start();
System.out.println(futureTask.get());
}
}
自然终止java线程
自然终止线程的方式:之然执行完毕或者式抛出未处理的异常。建议使用interrupt()终端一个线程,并非强行关闭这个线程,只是将线程的中断标志位置为true,线程是否中断,是由线程本身决定的。
- 使用interrupt() 函数终止线程
//终止实现了Runnable的线程
public class EndRunnable {
public static class ThreadA implements Runnable {
@Override
public void run() {
String name = Thread.currentThread().getName();
while(!Thread.currentThread().isInterrupted()) {
System.out.println(name+" is run!");
}
System.out.println(name+" interrupt flag is "+
Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
ThreadA threadA = new ThreadA();
Thread endThread = new Thread(threadA, "endThread");
endThread.start();
Thread.sleep(2000);
endThread.interrupt();
}
}
//终止继承自Thread的线程
public class EndThread {
private static class ThreadA extends Thread {
public ThreadA(String name) {
super(name);
}
@Override
public void run() {
String name = Thread.currentThread().getName();
while(!Thread.currentThread().isInterrupted()) {
System.out.println(name+" is run!");
}
System.out.println(name+" interrupt flag is "+
Thread.currentThread().isInterrupted());
}
}
public static void main(String[] args) throws InterruptedException {
ThreadA threadA = new ThreadA("Thread");
threadA.start();
threadA.sleep(2000);//反正就是睡眠一会儿
threadA.interrupt();
}
}
- 异常终止代码
catch的代码块里面必须要写interrupt,否则这个代码不会停下来。因为在InterrupotException中,线程的中断标志位会被复位成为false。
public class EndInterrupt {
private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:HH-mm-ss_SSSS");
private static class ThreadA extends Thread {
public ThreadA(String name) {
super(name);
}
@Override
public void run() {
String name = getName();
while(!isInterrupted()) {
try {
System.out.println(name+":"+sdf.format(new Date()));
sleep(2000);
} catch (InterruptedException e) {
System.out.println("Isinterrupt()---1:"+isInterrupted());
// interrupt();
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadA threadA = new ThreadA("Thread");
threadA.start();
threadA.sleep(200);//反正就是睡眠一会儿
threadA.interrupt();
}
}
线程的几种状态:
线程的几种状态.png关于守护线程
守护线程和主线程同生共死,不论在什么位置,只要主程序结束了,那么守护线程也会随着主子远去~~~~
- 相关代码
public class Deamon {
public static class ThreadA implements Runnable {
@Override
public void run() {
try{
while(true) {
System.out.println(Thread.currentThread().getName()+" is running!");
}
}finally {
System.out.println("hahahahhahah");
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadA threadA = new ThreadA();
Thread thread = new Thread(threadA);
thread.setDaemon(true);
thread.start();
Thread.sleep(2);
System.out.println("主程序执行完毕了啦~~~");
}
}