线程概念
一:程序 进程 线程
- 程序:Program 编写的代码,指令集,静态概念
- 进程:Process 操作系统调度程序,动态概念 作为资源分配的单位
- 线程:Thread 进程内多条执行路径 轻量级进程 调度和执行的单位 线程使用的资源是它所属进程的资源 只能共享资源 除CPU外不会为线程分配内存
线程创建
一:继承Thread + 重写run()方法Rabbit.javapublic class Rabbit extends Thread { public void run() { for(int i=0; i<5; i++) { System.out.println("Rabbit: " + i); } } }
启动:创建子类对象 + 调用子类对象.start()方法RabbitApp.java
public class RabbitApp { public static void main(String[] args) { Rabbit rabbit = new Rabbit(); //Tortoise tortoise = new Tortoise(); rabbit.start(); //tortoise.start(); } }
二:实现Runnable接口 + 重写run()方法Programmer.javapublic class Programmer implements Runnable { @Override public void run() { for(int i=0; i<5; i++) { System.out.println("Programmer: " + i); } } }
启动:创建真实角色
创建代理角色:Thread + 对真实角色的引用
代理角色.start()
ProgrammerApp.java
public class ProgrammerApp { public static void main(String[] args) { Programmer programmer = new Programmer(); Thread proxy = new Thread(programmer); proxy.start(); //for(int i=0; i<5; i++) { // System.out.println("main: " + i); //} } }
推荐:使用接口
- 避免单继承局限性
- 便于共享资源
三:创建Callable实现类 + 重写call()方法 可以抛检查时异常 前面的run()方法是不能抛异常的
线程状态
一:线程状态转换图
新生状态:用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)就绪状态:处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列,等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为”CPU调度“。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。运行状态:在运行状态的线程执行自己的run方法中,代码直到调用其他方法而终止,或等待某资源而阻塞或完成任务而死亡。如果过在给定的时间片内没有执行结束,就会被系统给换下来回到等待执行状态。运行状态:处于就绪状态的线程获得CPU时间片后,进入运行状态,真正开始执行run方法。阻塞状态:处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续执行。死亡状态:死亡状态是线程生命周期中的最后一个阶段。线程死亡的原因有两个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性的终止,如通过执行stop或destroy方法来终止一个线程【不推荐使用这两个方法。前者会产生异常,后者是强制终止,不会释放锁。】
停止线程
一:自然终止 线程体自然执行完毕二:外部干涉
- 线程体中定义线程体使用的标识
- 线程体使用该标识
- 提供对外的方法改变该标识
- 外部根据条件调用该方法即可
StopDemo01.javapublic class StopDemo01 { public static void main(String[] args) { Study study = new Study(); Thread thread = new Thread(study); thread.start(); for(int i=0; i<100; i++) { if(i==50) { study.stop(); } System.out.println("main thread->" + i); } } } class Study implements Runnable { private boolean flag = true; public void run() { while(flag) { System.out.println("study thread..."); } } public void stop() { this.flag = false; } }
线程阻塞
一:join 合并线程JoinDemo01.java二:yield 暂停自己的线程 staticpublic class JoinDemo01 extends Thread { public static void main(String[] args) throws Exception { JoinDemo01 joindemo01 = new JoinDemo01(); Thread t = new Thread(joindemo01); t.start(); for(int i=0; i<100; i++) { if(i==50) { t.join(); //main阻塞 } System.out.println("main thread..." + i); } } public void run() { for(int i=0; i<100; i++) { System.out.println("join thread..." + i); } } }<strong> </strong>
YeildDemo01.java三:sleep 休眠,不释放锁 staticpublic class YieldDemo01 extends Thread { public static void main(String[] args) { JoinDemo01 joindemo01 = new JoinDemo01(); Thread t = new Thread(joindemo01); t.start(); for(int i=0; i<100; i++) { if(i%10==0) { Thread.yield(); //暂停本线程main } System.out.println("main thread..." + i); } } public void run() { for(int i=0; i<100; i++) { System.out.println("yield thread..." + i); } } }
- 与时间相关:倒计时
- 模拟网络延时
SleepDemo01.javapublic class SleepDemo01 { public static void main(String[] args) throws Exception { int num = 10; while(num>=0) { Thread.sleep(1000); System.out.println(num); num--; } } }
线程基本信息
Thread.currentThread() //当前线程 staticsetName() //设置名称getName() //获取名称isAlive() //判断状态优先级:概率大小,不是绝对的先后顺序setPriority() //设置优先级大小getPriority() //获取优先级
MyThready.java
InfoDemo01.javapublic class MyThread implements Runnable { private boolean flag = true; private int num = 0; public void run() { while(flag) { System.out.println(Thread.currentThread().getName() + "->" + num); num++; } } public void stop() { this.flag = !this.flag; } }
InfoDemo02.javapublic class InfoDemo01 { public static void main(String[] args) throws Exception { MyThread mythread = new MyThread(); Thread proxy = new Thread(mythread); proxy.setName("test"); System.out.println(proxy.getName()); System.out.println(Thread.currentThread().getName()); proxy.start(); Thread.sleep(100); mythread.stop(); } }
package com.cho3en1.thread.info; public class InfoDemo02 { public static void main(String[] args) throws Exception { MyThread mythread1 = new MyThread(); MyThread mythread2 = new MyThread(); Thread t1 = new Thread(mythread1); Thread t2 = new Thread(mythread2); t1.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); t1.start(); t2.start(); Thread.sleep(200); mythread1.stop(); mythread2.stop(); } <h2>}</h2>
线程同步与锁定
同步:并发 多个线程访问同一份资源 确保资源安全synchronized -> 同步
一:同步块synchronized(引用类型|this|类.class) {}
二:同步方法synchronizedSynDemo01.javapublic class SynDemo01 { public static void main(String[] args) { Web12306 w = new Web12306(); Thread p1 = new Thread(w, "黄牛1"); Thread p2 = new Thread(w, "黄牛2"); Thread p3 = new Thread(w, "黄牛3"); p1.start(); p2.start(); p3.start(); } } class Web12306 implements Runnable { private boolean flag = true; private int num = 50; @Override public void run() { while(flag) { test1(); } } public synchronized void test1() { if(num<=0) { flag = false; return; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "抢到了" + num--); } }
三:死锁SynDemo02.javapublic class SynDemo02 { public static void main(String[] args) { Test t1 = new Test(); Test t2 = new Test(); t1.flag = true; t2.flag = false; Thread proxy1 = new Thread(t1); Thread proxy2 = new Thread(t2); proxy1.start(); proxy2.start(); } } class Test implements Runnable { public boolean flag; static Object goods = new Object(); static Object money = new Object(); public void run() { while(true) { test(); } } public void test() { if(flag == true) { synchronized (goods) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (money) { System.out.println("一手给钱"); } } } if(flag == false) { synchronized (money) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (goods) { System.out.println("一手给货"); } } } } }