线程的创立形式
继承Thread
继承Therad类,并重写run()办法

public class T1 extends Thread{

@Overridepublic void run(){}public static void main(String[] str){    T1 t1=new T1();    t1.start();}

}
实现Runnable
实现Runnable,并重写run()办法,调用时应用Therad包裹

public class T1 implements Runnable{

@Overridepublic void run(){}public static void main(String[] str){    T1 t1=new T1();    Thread t2=new Thread(t1);    t2.start();}

}
lambda 简化
new Thread(

()->{}

).start();
线程的五大状态
image.png

状态 形容
创立状态 new进去的时候就是创立状态
就绪状态 调用是start() 就是就绪状态
运行状态 就绪状态失去cpu的调度,进入运行状态
阻塞状态 线程运行暂停,就是阻塞状态,例如调用sleep(),阻塞状态之后会进入就绪状态
死亡状态 线程执行结束或被终止
线程的操作
线程的进行
JDK提供的Stop(),destroy()都已废除,不倡议用
倡议应用一个标记位进行终止变量,或等线程本人进行

public class T1 implements Runnable{

private Boolean f=true;@Overridepublic void run(){    int a=0;    while(f){            System.out.println(a++);    }}public void stop(){    f=false;}public static void main(String[] str){    T1 t1=new T1();    Thread t2=new Thread(t1);    t2.start();    for (int a=0;a<1000;a++){        if (a==900){            t1.stop();        }    }}

}
线程的休眠 sleep()
sleep指定线程阻塞的毫秒数,毫秒即千分之一秒
sleep存在异样
sleep执行实现后进入就绪状态
sleep不会开释锁

new Thread(()->{

                try {                     int a=10;                    while(a>=0){                        Thread.sleep(1000);                        System.out.println(a--);                    }                } catch (InterruptedException e) {                    e.printStackTrace();                }            }).start();

线程礼让 yield()
将执行的线程暂停但不阻塞
将线程从运行状态转为就绪状态
礼让之后调度状态随机

Thread thread1 = new Thread(() -> {

        System.out.println("线程开始");        Thread.yield();        System.out.println("线程进行");    });    Thread thread = new Thread(() -> {        System.out.println("线程开始1");        Thread.yield();        System.out.println("线程进行1");    });    thread1.start();    thread.start();;

线程插队 join()
Join合并线程,当此线程执行实现后,能力执行其余线程,其余线程阻塞

public static void main(String[] args) {

    Thread thread1 = new Thread(() -> {        for(int i=0;i<1000;i++) {            System.out.println("线程VIP");        }    });    for (int i=0;i<1000;i++){        if (i==900){            try {                thread1.join();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        System.out.println(i);    }}

守护线程
线程分为用户线程和守护线程
虚拟机必须确保用户线程执行结束,不必期待守护线程执行结束
守护线程如记录日志,监控内存,垃圾回收等

并发
同一个对象被多个线程同时操作就是并发

线程同步
为了解决多个并发问题,引入锁机制synchronized ,党当一个对象取得锁,独占资源,其余线程必须期待,应用后开释锁即可
锁带来的问题

一个线程持有锁会导致其余须要此锁的线程挂起
多个线程竞争,加锁开释锁引起性能问题
高优先级线程期待低优先级呈现优先级倒置,引起性能问题
锁就是要锁变动的对象

同步办法
对于简略的不是批改其余对象的办法,能够间接应用synchronized锁定以后办法

写法就是间接在办法中增加synchronized 关键字

@Override

public synchronized void run() {    while (f){        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"买到"+p--);        if (p<=0){            f=false;            return;        }    }}

同步块
当线程批改了以后办法外的其余对象,就须要应用同步块

格局:

synchronized (加锁对象){
线程办法
}
例如:

@Override

public  void run() {        while (f){            synchronized (qian){            if (qian.getM()<=0){                f=false;                break;            }            qian.setM(qian.getM()-yici);            System.out.println("取出"+yici+"还剩"+qian.getM());        }    }}

Lock锁
Lock是显式锁(手动开关),synchronization是隐式锁,出了作用域主动开释
Lock没有办法锁,只有代码块锁
Lock锁性能更好,扩展性更高
优先应用Lock,其次同步块,其次同步办法

罕用Lock锁,ReentrantLock (可重入锁)

private final ReentrantLock a=new ReentrantLock();@Overridepublic  void run() {    while (f){        try {            a.lock();            if (p<=0){                f=false;                return;            }            Thread.sleep(100);            System.out.println(Thread.currentThread().getName()+"买到"+p--);        } catch (InterruptedException e) {            e.printStackTrace();        }finally {            a.unlock();        }    }}

死锁
死锁即两个或多个线程,都在期待对方开释锁,如多个同步块嵌套

产生死锁的四个必要条件
互斥条件
一个资源每次只能被一个过程应用
申请与放弃条件
线程阻塞时对已持有锁不开释
不剥夺条件
过程以取得的资源,在未应用完之前,不能强行剥夺
循环期待条件
多个过程之间闭环期待开释
线程通信
生产生产模式
管程法
即线程独特操作一个容器,生产者生产的产品放到容器的产品汇合,消费者从产品汇合中取出产品

生产者:
产品汇合满了,线程期待,期待消费者生产后唤醒生产者
没满就存入,而后唤醒消费者

消费者:
没产品了就期待,生产者生产了产品后会唤醒消费者
有产品就生产,而后唤醒生产者

public class Test6 {

public static void main(String[] args) {    容器 r=new 容器();    生产者 s=new 生产者(r);    消费者 x=new 消费者(r);    Thread ts=new Thread(s);    Thread tx=new Thread(x);    ts.start();    tx.start();}

}

class 生产者 implements Runnable{

容器 r;public 生产者(容器 r) {    this.r = r;}@Overridepublic  void run() {    for (int a=0;a<100;a++){        r.放入(new 产品(a));        System.out.println("生产了"+a);    }}

}
class 消费者 implements Runnable{

容器 r;public 消费者(容器 r) {    this.r = r;}@Overridepublic  void run() {    for (int a=0;a<100;a++){        System.out.println("------------取出了"+r.取出().id);    }}

}
class 产品{

int id;public 产品(int id) {    this.id = id;}

}
class 容器{

产品[] 产品容器=new 产品[20];int 数量=0;public synchronized void 放入(产品 c){        try {            if (数量==产品容器.length) {                this.wait();            }            产品容器[数量]=c;            数量++;            this.notifyAll();        } catch (InterruptedException e) {            e.printStackTrace();        }    }public synchronized 产品 取出() {    try {        if (数量==0){            this.wait();        }    }catch (Exception e){    }   数量 --;    产品 c=产品容器[数量];    this.notifyAll();    return c;}

}
信号灯法
信号灯法就是在交互层,搁置一个标记位,如果为真,生产者操作,如果为假,消费者操作,操作完都会取反。

public class Test7 {

public static void main(String[] args) {    交互 j=new 交互();    生产 s=new 生产(j);    生产 x=new 生产(j);    Thread ts=new Thread(s);    Thread tx=new Thread(x);    ts.start();    tx.start();}

}
class 生产 implements Runnable{

交互 j;public 生产(交互 j) {    this.j = j;}@Overridepublic void run() {    for (int a=0;a<100;a++){        j.生产("节目---"+a);    }}

}
class 生产 implements Runnable{

交互 j;public 生产(交互 j) {    this.j = j;}@Overridepublic void run() {    for (int a=0;a<100;a++){        j.生产();    }}

}
class 交互{

String a="";boolean f=true;public synchronized void 生产(String s){    if (!f){        try {            this.wait();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    System.out.println("生产了"+s);    this.a=s;    this.notifyAll();    f=!f;}public synchronized void 生产(){    if (f){        try {            this.wait();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    System.out.println("生产了"+a);    this.notifyAll();    f=!f;}

}
线程池