JavaEE--线程基础(中)


JavaEE--线程基础(中)_第1张图片
JavaEE--线程基础(中)_第2张图片
JavaEE--线程基础(中)_第3张图片
JavaEE--线程基础(中)_第4张图片


JavaEE--线程基础(中)_第5张图片


JavaEE--线程基础(中)_第6张图片

JavaEE--线程基础(中)_第7张图片
JavaEE--线程基础(中)_第8张图片


JavaEE--线程基础(中)_第9张图片
JavaEE--线程基础(中)_第10张图片


JavaEE--线程基础(中)_第11张图片


JavaEE--线程基础(中)_第12张图片
JavaEE--线程基础(中)_第13张图片
JavaEE--线程基础(中)_第14张图片


JavaEE--线程基础(中)_第15张图片

JavaEE--线程基础(中)_第16张图片


JavaEE--线程基础(中)_第17张图片


JavaEE--线程基础(中)_第18张图片
JavaEE--线程基础(中)_第19张图片


JavaEE--线程基础(中)_第20张图片
JavaEE--线程基础(中)_第21张图片
JavaEE--线程基础(中)_第22张图片
JavaEE--线程基础(中)_第23张图片


JavaEE--线程基础(中)_第24张图片
在这里插入图片描述


JavaEE--线程基础(中)_第25张图片
JavaEE--线程基础(中)_第26张图片


volatile 修饰的变量, 能够保证 “内存可见性”
JavaEE--线程基础(中)_第27张图片


JavaEE--线程基础(中)_第28张图片

JavaEE--线程基础(中)_第29张图片
JavaEE--线程基础(中)_第30张图片
JavaEE--线程基础(中)_第31张图片


JavaEE--线程基础(中)_第32张图片
JavaEE--线程基础(中)_第33张图片
上述过程的完整代码如下:

public class Demo14 {
    //使用locker对象负责加锁,wait,notify
    private static Object locker=new Object();
    public static void main(String[] args) {
        Thread t1=new Thread(() ->{
           while(true){
               synchronized (locker){
                   System.out.println("t1 wait开始");
                   try {
                       locker.wait();
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println("t1 wait结束");
               }
           }
        });
        t1.start();

        Thread t2=new Thread(() ->{
           while(true){
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               synchronized (locker){
                   System.out.println("t2 notify开始");
                   locker.notify();
                   System.out.println("t2 notify结束");
               }
           }
        });
        t2.start();
    }
}

其中,我们观察到notify的开始和结束的过程是非常快的


JavaEE--线程基础(中)_第34张图片
JavaEE--线程基础(中)_第35张图片
在这里插入图片描述


JavaEE--线程基础(中)_第36张图片


下面介绍代码案例

JavaEE--线程基础(中)_第37张图片

JavaEE--线程基础(中)_第38张图片****
饿汉模式
JavaEE--线程基础(中)_第39张图片

JavaEE--线程基础(中)_第40张图片
JavaEE--线程基础(中)_第41张图片
JavaEE--线程基础(中)_第42张图片


懒汉模式
类加载的时候不创建实例. 第一次使用的时候才创建实例.
因为只有使用getInstance的时候,才会new出来一个对象;而在饿汉模式下,instance被当做一个类的属性,在类的加载的时候就被创建了。

JavaEE--线程基础(中)_第43张图片


JavaEE--线程基础(中)_第44张图片
JavaEE--线程基础(中)_第45张图片


JavaEE--线程基础(中)_第46张图片
JavaEE--线程基础(中)_第47张图片


JavaEE--线程基础(中)_第48张图片
JavaEE--线程基础(中)_第49张图片

JavaEE--线程基础(中)_第50张图片


JavaEE--线程基础(中)_第51张图片
JavaEE--线程基础(中)_第52张图片


JavaEE--线程基础(中)_第53张图片
JavaEE--线程基础(中)_第54张图片


JavaEE--线程基础(中)_第55张图片


JavaEE--线程基础(中)_第56张图片


JavaEE--线程基础(中)_第57张图片
JavaEE--线程基础(中)_第58张图片

JavaEE--线程基础(中)_第59张图片
JavaEE--线程基础(中)_第60张图片


JavaEE--线程基础(中)_第61张图片
JavaEE--线程基础(中)_第62张图片


JavaEE--线程基础(中)_第63张图片
上述过程的完整代码如下:

import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;

//生产者消费者模型
public class Demo18 {
    public static void main(String[] args) {
        //建一个阻塞队列,作为交易场所
        BlockingDeque<Integer> queue=new LinkedBlockingDeque<>();

        //一个线程负责生产
        Thread t1=new Thread(() ->{
            int count=0;
           while(true){
               try {
                   queue.put(count);
                   System.out.println("生产的元素为:"+count);
                   count++;
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });

        //一个线程负责消耗
        Thread t2=new Thread(() ->{
            while(true){
                try {
                    Integer n=queue.take();
                    System.out.println("消耗的元素为:"+n);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
    }
}


阻塞队列的模拟实现
JavaEE--线程基础(中)_第64张图片
JavaEE--线程基础(中)_第65张图片
JavaEE--线程基础(中)_第66张图片

下面首先实现一般的队列
JavaEE--线程基础(中)_第67张图片
上述过程的代码如下:

class MyBlockingQueue{
    //使用循环队列来表示这个阻塞队列
    private String[] items=new String[1000];
    //队列的头部
    int head=0;
    //tail:队列的尾部的下一个元素. 总的来说, 队列中有效元素的范围 [head, tail)
    // 当 head 和 tail 相等(重合), 相当于空的队列.
    int tail=0;
    //size表示队列当前的元素个数
    int size=0;

    public void put(String elem){
        if(size>=items.length){//队列满
            return;
        }
        items[tail]=elem;
        tail++;
        if(tail>= items.length){
            tail=0;
        }
        size++;
    }
    public String take(){
        if(size==0){
            return null;
        }
        String elem=items[head];
        head++;
        if(head>= items.length){
            head=0;
        }
        size--;
        return elem;
    }
}
public class Demo19 {
    public static void main(String[] args) {
    MyBlockingQueue queue=new MyBlockingQueue();
    queue.put("aaa");
    queue.put("bbb");
    queue.put("ccc");
    queue.put("ddd");

    String elem= queue.take();
    System.out.println("elem="+elem);
    elem= queue.take();
    System.out.println("elem="+elem);
    elem= queue.take();
    System.out.println("elem="+elem);
    }
}

JavaEE--线程基础(中)_第68张图片

考虑线程安全性JavaEE--线程基础(中)_第69张图片


JavaEE--线程基础(中)_第70张图片

实现阻塞
JavaEE--线程基础(中)_第71张图片

JavaEE--线程基础(中)_第72张图片
在这里插入图片描述
JavaEE--线程基础(中)_第73张图片


上述实现过程的最终代码如下:

class MyBlockingQueue{
    //使用循环队列来表示这个阻塞队列
    private String[] items=new String[10];
    //队列的头部
    volatile int head=0;
    //tail:队列的尾部的下一个元素. 总的来说, 队列中有效元素的范围 [head, tail)
    // 当 head 和 tail 相等(重合), 相当于空的队列.
    volatile int tail=0;
    //size表示队列当前的元素个数
    volatile int size=0;

    public void put(String elem) throws InterruptedException {
        synchronized (this){
            while(size>=items.length){//队列满
                //return;
                this.wait();
            }
            items[tail]=elem;
            tail++;
            if(tail>= items.length){
                tail=0;
            }
            size++;
            this.notify();
        }
    }
    public String take() throws InterruptedException {
        synchronized (this){
            while(size==0){
               // return null;
                this.wait();
            }
            String elem=items[head];
            head++;
            if(head>= items.length){
                head=0;
            }
            size--;
            this.notify();
            return elem;
        }
    }
}
public class Demo19 {
    public static void main(String[] args) {
/*    MyBlockingQueue queue=new MyBlockingQueue();
    queue.put("aaa");
    queue.put("bbb");
    queue.put("ccc");
    queue.put("ddd");

    String elem= queue.take();
    System.out.println("elem="+elem);
    elem= queue.take();
    System.out.println("elem="+elem);
    elem= queue.take();
    System.out.println("elem="+elem);*/
        //创建两个线程,表示生产者和消费者
        MyBlockingQueue queue=new MyBlockingQueue();
        Thread t1=new Thread(() ->{
            int count=0;
           while (true){
               try {
                   queue.put(count + "");
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println("生产"+count);
               count++;
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        Thread t2=new Thread(() ->{
            while (true){
                String elem= null;
                try {
                    elem = queue.take();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消耗"+elem);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
        t2.start();
    }
}


你可能感兴趣的:(Java-EE,java-ee,java)