java进程以及线程(Thread)
什么是进程
进程是程序的一次执行过程,是系统运行的基本单位,因此进程是动态的,就好比运行一个程序
从开始到结束的一个过程,简单来说一个进程就是一个程序。
什么是线程
线程与进程相似,但是一个进程里可以有多个线程,线程的负担比进程要小很多,所以线程也被称之为轻量级进程。
实现多线程的三种方式
一、继承Thread
调用start()方法重写run()方法
特点:继承 简单 但是 不灵活 数据不共享
创建MyThread类
示例:
public class MyThread1 extends Thread{ // 重写 run方法 private int tickect=5; // 重写 run方法 @Override public void run() { // while(tickect>0){ // 票减1 System.out.println(Thread.currentThread().getName()+"卖出去了一张票,还剩:"+tickect--); } } } |
// 多个线程同时启动 public static void main(String[] args) { // MyThread1 myThread1 = new MyThread1(); myThread1.setName("ndt"); // 第一个线程 myThread1.start(); try { myThread1.join();// ndt } catch (InterruptedException e) { throw new RuntimeException(e); } MyThread1 myThread2 = new MyThread1(); myThread2.setName("test"); // 第一个线程 myThread2.start(); } |
ndt卖出去了一张票,还剩:5 ndt卖出去了一张票,还剩:4 ndt卖出去了一张票,还剩:3 ndt卖出去了一张票,还剩:2 ndt卖出去了一张票,还剩:1 test卖出去了一张票,还剩:5 test卖出去了一张票,还剩:4 test卖出去了一张票,还剩:3 test卖出去了一张票,还剩:2 test卖出去了一张票,还剩:1 |
继承Thread实现多线程不好的地方,线程和任务内容耦合性太强,这个线程只能执行run方法中编写任务内容。无法执行别的任务,,且这个任务也只能被这个线程执行。
二、实现Runnable接口
实现接口 灵活 数据共享
调用的时候
- 创建一个多线程的实例
- 将线程的实例存放到Thread里面
- 调用start方法
示例:
public class MyThreadLirang implements Runnable{ private int tickect=5; // 重写 run方法 @Override public void run() { // while(tickect>0){ String name = Thread.currentThread().getName(); if(name.equals("test1")){ Thread.yield(); } // 票减1 System.out.println(name+"卖出去了一张票,还剩:"+tickect--); } } } |
// 多个线程同时启动 public static void main(String[] args) { MyThreadLirang myThread1 = new MyThreadLirang(); Thread thread = new Thread(myThread1,"test1"); Thread thread2 = new Thread(myThread1,"test2"); // thread2.setName("test2"); thread.start(); thread2.start(); } |
Process finished with exit code 0 |
三、实现 Callable接口
实现数据的共享
有返回值
可以抛出异常
创建一个类 实现Callable接口 重写call方法
示例:
public class MyThread3 implements Callable { private int tickect=5; @Override public Object call() throws Exception { // while(tickect>0){ // 票减1 System.out.println(Thread.currentThread().getName()+"卖出去了一张票,还剩:"+tickect--); } return "ok"; } } |
// 多个线程同时启动 public static void main(String[] args) { // new 一次 MyThread3 myThread3 = new MyThread3();// 实例 FutureTask<String> futureTask = new FutureTask<>(myThread3); FutureTask<String> futureTask2 = new FutureTask<>(myThread3); Thread thread = new Thread(futureTask,"yyl1"); Thread thread2 = new Thread(futureTask2,"yyl2"); thread.start(); thread2.start(); // 获取返回值 String s = null; try { s = futureTask.get(); } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); } System.out.println(s); } |
yyl1卖出去了一张票,还剩:5 yyl2卖出去了一张票,还剩:4 yyl1卖出去了一张票,还剩:3 yyl2卖出去了一张票,还剩:2 yyl1卖出去了一张票,还剩:1 ok |
四、join()
当前的线程执行完其他的线程才能够执行
示例
public class MyThread1 extends Thread{ // 重写 run方法 private int tickect=5; // 重写 run方法 @Override public void run() { // while(tickect>0){ // 票减1 System.out.println(Thread.currentThread().getName()+"卖出去了一张票,还剩:"+tickect--); } } } |
// 多个线程同时启动 public static void main(String[] args) { // MyThread1 myThread1 = new MyThread1(); myThread1.setName("ndt"); // 第一个线程 myThread1.start(); try { myThread1.join();// ndt } catch (InterruptedException e) { throw new RuntimeException(e); } MyThread1 myThread2 = new MyThread1(); myThread2.setName("test"); // 第一个线程 myThread2.start(); } |
ndt卖出去了一张票,还剩:5 ndt卖出去了一张票,还剩:4 ndt卖出去了一张票,还剩:3 ndt卖出去了一张票,还剩:2 ndt卖出去了一张票,还剩:1 test卖出去了一张票,还剩:5 test卖出去了一张票,还剩:4 test卖出去了一张票,还剩:3 test卖出去了一张票,还剩:2 test卖出去了一张票,还剩:1 |
五、线程中断
发出一个标记
中断 true
不中断 false
遇见sleep的时候 中断的标识会被清除 抛出异常
示例:
public class MyThreadZhongduan extends Thread{ // 重写 run方法 private int tickect=5; // 重写 run方法 @Override public void run() { // while(tickect>0){ try { Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } // 查看当前的休眠的状态 System.out.println("中断:"+Thread.currentThread().isInterrupted()); // 票减1 System.out.println(Thread.currentThread().getName()+"卖出去了一张票,还剩:"+tickect--); } } } |
// 多个线程同时启动 public static void main(String[] args) { // MyThreadZhongduan myThread1 = new MyThreadZhongduan(); myThread1.setName("ndt"); MyThreadZhongduan myThread2 = new MyThreadZhongduan(); myThread2.setName("test"); // 第一个线程 myThread1.start(); myThread1.interrupt();// // 第一个线程 myThread2.start(); } |
Exception in thread "ndt" java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted at com.aaa.xaincheng1.MyThreadZhongduan.run(MyThreadZhongduan.java:17) Caused by: java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.aaa.xaincheng1.MyThreadZhongduan.run(MyThreadZhongduan.java:15) 中断:false test卖出去了一张票,还剩:5 中断:false test卖出去了一张票,还剩:4 中断:false test卖出去了一张票,还剩:3 中断:false test卖出去了一张票,还剩:2 中断:false test卖出去了一张票,还剩:1 |