1.什么是进程?什么是线程?
进程是一个应用程序(1个进程是一个软件)
线程是一个进程中的执行场景/执行单元
一个进程可以启动多个线程
2.对于java程序来说,当在DOS命令窗口中输入:
java HelloWorld 回车之后
会先启动JVM,而JVM就是一个进程
JVM再启动一个主线程调用main方法
同时再启动一个垃圾回收线程负责看护,回收垃圾
最起码,现在的java程序中至少有两个线程并发,
一个是垃圾回收线程,一个是执行main方法的主线程
3.进程和线程是什么关系?举例
阿里巴巴:进程
马云:阿里巴巴的一个线程
童文红:阿里巴巴的一个线程
注意:
进程A和进程B的内存独立不共享
线程A和线程B呢?
在java语言中:
线程A和线程B,堆内存和方法区内存共享
但是栈内存独立,一个线程一个栈
假设启动10个线程,会有10个栈空间,每个栈和每个栈之间
互不干扰,各自执行各自的,这就是多线程并发
使用了多线程机制后, main方法结束只是主线程结束了,主栈空了,其他的栈(线程)可能还在
压栈弹栈
4.实现线程的两种方式:
第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法
// 定义线程类 public class MyThread extends Thread{ public void run(){ } } // 创建线程对象 MyThread t = new MyThread(); // 启动线程 t.start();
第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法
//定义一个可运行的类 public class MyRunnable implements Runnable{ public void run(){ } } // 创建线程对象 Thread t = new Thread(new MyRunnable()); // 启动线程 t.start();
注意:第二种方式实现接口比较常用,因为一个类实现了接口,它还可以去继承
其他的类,更灵活
5.关于线程对象的生命周期?
6.合理终止线程执行
public static void main(String[] args) { myRunnable4 r = new myRunnable4(); Thread t = new Thread(r); t.setName("t"); t.start(); // 模拟五秒 try { t.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } //终止线程 // 想要什么时候终止t的执行,就把标记修改为false r.run = false; } class myRunnable4 implements Runnable{ // 打一个布尔标记 boolean run = true; @Override public void run() { for (int i = 0; i < 10; i++) { if(run){ System.out.println(Thread.currentThread().getName() + "--->" + i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else{ // 终止当前线程 return; } } } }
7.终止线程睡眠
public static void main(String[] args) { Thread t = new Thread(new myRunnable2()); t.setName("t"); t.start(); // 希望五秒后,t线程醒来 try { t.sleep(1000 * 5); } catch (InterruptedException e) { // 打印异常信息 e.printStackTrace(); } // 中断t线程的睡眠(这种中断睡眠的方式依靠了java的异常处理机制 ) t.interrupt();// 干扰 } class myRunnable2 implements Runnable{ // 重点:run()当中的异常不能throws,只能try catch // 因为run()方法在父类中没有抛出任何异常,子类不能比父类抛出更多的异常 @Override public void run() { System.out.println(Thread.currentThread().getName() + "--> begin"); try { // 睡眠一年 Thread.sleep(1000 * 60 * 60 * 24 * 365); } catch (InterruptedException e) { // e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "--> over"); } }
8..什么时候数据在多线程并发的环境下会存在安全问题呢?
三个条件 :
条件1:多线程并发
条件2:有共享数据
条件3:共享数据有修改的行为
满足以上三个条件之后,就会存在线程安全问题
异步编程模型:
线程t1和线程t2,各自执行各自的,t1不管t2,t2不管t1
谁也不需要等谁,这种编程模型叫做:异步编程模型
其实就是多线程并发(效率较高)
同步编程模型:
线程t1和线程t2,在线程 1执行的时候,必须等待t2线程执行结束,
或者说在t2线程执行的时候,必须等待t1线程执行结束,
两个线程之间发生了等待关系,这就是同步编程模型
效率较低,线程排队执行
9.join
public static void main(String[] args) { System.out.println("Main Begin"); Thread t = new Thread(new MyRunnable()); t.setName("t"); t.start(); // 合并线程 try { t.join(); // t合并到当前线程中,当前线程受阻塞,t线程执行直到结束 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Main Over"); } } class MyRunnable1 implements Runnable{ @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println(Thread.currentThread().getName() + "--->" + i); } } }