程序、进程和线程html
1、程序java
2、进程安全
进程是资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例,即运行中的程序。网络
一个运行着的程序,可能有多个进程。进程在操做系统中执行特定的任务。多线程
程序运行时系统就会建立一个进程,并为它分配资源,而后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。ide
3、 线程函数
线程是程序中执行的线程。Java虚拟机容许应用程序同时运行多个执行线程。测试
每一个线程都有优先权。 具备较高优先级的线程优先于具备较低优先级的线程执行。 每一个线程可能也可能不会被标记为守护进程。 当在某个线程中运行的代码建立一个新的
Thread
对象时,新线程的优先级最初设置为等于建立线程的优先级,而且当且仅当建立线程是守护进程时才是守护进程线程。this当Java虚拟机启动时,一般会有一个非守护进程线程(一般调用某个指定类的名为
main
的方法)。 Java虚拟机继续执行线程,直到发生如下任一状况:操作系统
- 已调用类
Runtime
的exit
方法,而且安全管理器已容许执行退出操做。- 经过调用
run
方法返回或抛出超出run
方法传播的异常,全部非守护程序线程的线程都已死亡。
建立线程方式一:继承Thread类,重写run()方法,调用start()开启线程
public class MyThread extends Thread{ @Override public void run() { //子线程方法 for (int i = 0; i < 20; i++) { System.out.println("我是子线程" + i); } } public static void main(String[] args) { //开启子线程 new MyThread().start(); for (int i = 0; i < 20; i++) { System.out.println("我是主线程" + i); } } }
执行结果
能够发现,主线程和子线程是”同时“进行的。
Thread类实现了Runnable接口,内部经过静态代理调用了run()方法
public class MyThread implements Runnable{ @Override public void run() { //子线程方法 for (int i = 0; i < 20; i++) { System.out.println("我是子线程" + i); } } public static void main(String[] args) { //建立线程对象,代理线程 new Thread(new MyThread()).start(); for (int i = 0; i < 20; i++) { System.out.println("我是主线程" + i); } } }
使用方法基本和继承Thread类相同,执行结果也类似。
示例代码
public class MyThread implements Callable<Boolean> { @Override public Boolean call() { //子线程方法 System.out.println("执行了子线程"); return true; } public static void main(String[] args) throws ExecutionException, InterruptedException { MyThread t1 = new MyThread(); //建立执行服务 ExecutorService ser = Executors.newFixedThreadPool(1); //提交执行 Future<Boolean> result1 = ser.submit(t1); //获取结果 boolean r1 = result1.get(); //关闭服务 ser. shutdownNow(); } }
建立状态:
Thread t = new Thread()
线程对象一旦建立就进入到了新生状态。
就绪状态:
当调用start()方法,线程当即进入就绪状态,但不意味着当即调度执行。
运行状态:
进入运行状态,线程才真正执行线程体的代码块。
阻塞状态:
当调用sleep, wait 或同步锁定时,线程进入阻塞状态,就是代码不往下执行,阻塞事件解除后,从新进入就绪状态,等待cpu调度执行。
不必定每一个线程都会进入阻塞状态
死亡状态:
线程中断或者结束,一旦进入死亡状态,就不能再次启动。
方法 | 说明 |
---|---|
setPriority(int newPriority) | 更改线程的优先级 |
static void sleep(long millis) | 在指定的毫秒数内让当前正在执行的线程休眠 |
void join() | 等待该线程终止 |
static void yield() | 暂停当前正在执行的线程对象,并执行其余线程 |
void interrupt() | 中断线程,别用这个方式 |
boolean isAlive() | 测试线程是否处于活动状态 |
使用标志位的例子
public class MyThread implements Runnable{ private boolean flag = true; @Override public void run() { //子线程方法 int i = 0; while (flag) { System.out.println("我是子线程" + i++); } } public void stop() { this.flag = false; } public static void main(String[] args) { MyThread thread = new MyThread(); new Thread(thread).start(); for (int i = 0; i < 1000; i++) { System.out.println("主线程" + i); if (i == 800) { thread.stop(); System.out.println("线程中止了"); } } } }
结果如图
线程休眠的例子:
public class MyThread{ public static void main(String[] args) throws InterruptedException { while (true) { Date date = new Date(System.currentTimeMillis()); System.out.println(new SimpleDateFormat("HH:mm:ss").format(date)); Thread.sleep(1000); } } }
每一秒输出当前时间,使用sleep(1000)来使得每次执行完休眠一秒。
示例
public class MyThread{ public static void main(String[] args) { Runnable runnable = () -> { System.out.println(Thread.currentThread().getName() + "线程开始"); Thread.yield(); //线程礼让 System.out.println(Thread.currentThread().getName() + "线程结束"); }; new Thread(runnable, "a").start(); new Thread(runnable, "b").start(); new Thread(runnable, "c").start(); } }
执行结果
能够发现每次的结果都不相同
能够想象成一个VIP线程,强制插队,查到当前线程,直到本身执行完毕。很是霸道
会使得线程阻塞。
public class MyThread{ public static void main(String[] args) throws InterruptedException { Runnable runnable = () -> { for (int i = 0; i < 10; i++) { System.out.println("VIP线程来了" + i); } }; Thread thread = new Thread(runnable); thread.start(); for (int i = 0; i < 50; i++) { if (i == 30) thread.join(); System.out.println("主线程" + i); } } }
结果如图
线程状态。线程能够处于如下状态之一:
线程在给定时间点只能处于一种状态。 这些状态是虚拟机状态,不反映任何操做系统线程状态。
经过如下代码演示线程状态的监听
public class MyThread{ public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(()->{ for (int i = 0; i < 5; i++) { try { Thread.sleep(500); } catch (InterruptedException ignored) {} } }); System.out.println(thread.getState()); thread.start(); while (thread.getState() != Thread.State.TERMINATED) { Thread.sleep(500); System.out.println(thread.getState()); } } }
运行结果
Java提供一个线程调度器来监控程序中启动后进入就绪状态的全部线程, 线程调度
器按照优先级决定应该调度哪一个线程来执行。
观察Thread类源代码,能够看到优先级在jdk中的定义
/** * The minimum priority that a thread can have. */ public static final int MIN_PRIORITY = 1; /** * The default priority that is assigned to a thread. */ public static final int NORM_PRIORITY = 5; /** * The maximum priority that a thread can have. */ public static final int MAX_PRIORITY = 10;
咱们能够经过
System.out.println(Thread.currentThread().getPriority());
来输出当前线程的优先级,能够获得默认优先级是5。
可使用如下方式改变或获取优先级
getPriority() //获得优先级 setPriority(int xxx) 设置优先级
若是设置的优先级超出限制,则会抛出一个IllegalArgumentException异常:
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) { throw new IllegalArgumentException(); }
优先级低只是意味着得到调度的几率低,并非优先级低就不会被调用了,这都是看CPU的调度。
最好在start前设置优先级
所谓守护线程,是指在程序运行的时候在后台提供一种通用服务的线程,好比垃圾回收线程就是一个很称职的守护者,而且这种线程并不属于程序中不可或缺的部分。所以,当全部的非守护线程结束时,程序也就终止了,同时会杀死进程中的全部守护线程。反过来讲,只要任何非守护线程还在运行,程序就不会终止。
用户线程和守护线程二者几乎没有区别,惟一的不一样之处就在于虚拟机的离开:若是用户线程已经所有退出运行了,只剩下守护线程存在了,虚拟机也就退出了。 由于没有了被守护者,守护线程也就没有工做可作了,也就没有继续运行程序的必要了。
演示,先定义两个线程,一个守护线程,一个普通线程
Thread daemon = new Thread(()->{ while (true) { System.out.println("守护线程..."); } }); Thread normal = new Thread(()->{ for (int i = 0; i < 10; i++) { System.out.println("子线程..."); } System.out.println("子线程结束"); });
而后设置守护线程
daemon.setDaemon(true);
启动两个线程后,能够看到,守护线程并无结束就中止了程序。