美文网首页
Java并发编程

Java并发编程

作者: DaemonXiao | 来源:发表于2019-04-27 20:48 被阅读0次

    余学习Java一年有余,然懵懵懂懂不得精髓,盖懒惫不肯专研,又或三天打渔两天晒网不能坚持。今习并发编程,愿持之以恒,悟得妙法。

    Java内存模型——同步的八种操作

    1. use(使用):作用于工作内存的变量,把工作内存中的一个变量值传递给执行引擎。
    2. assign(赋值):作用于工作内存的变量,把一个从执行引擎接收到的值赋给工作内存的变量。
    3. store(存储):作用于工作内存的变量,把工作内存中的一个变量的值传递到主内存中,以便于以后的write操作。
    4. write(写入):作用于主内存的变量,把store操作从工作内存中的一个变量的值传递到主内存的变量中。
    5. lock(锁定):作用于主内存的变量,把一个变量标识为一条线程独占状态。
    6. unlock(解锁):作用于主内存的变量,把一个处于锁定状态的变量释放出来,释放后的变量才可以被其它线程锁定。
    7. read(读取):作用于主内存的变量,把一个变量值从主内存传输到工作线程的工作内存中,以便以后的load动作使用。
    8. load(载入):作用于工作内存的变量,把read操作从主内存中得到的变量值放入工作内存的变量副本中。

    同步规则

    • 如果要把一个变量从主内存中复制到工作内存,就需要按顺序地执行read和load操作,如果把变量从工作内存中同步到主内存中,就要按顺序地执行stroe和write操作。但Java内存模型只要求上述操作必须按顺序执行,而没有保证必须是连续执行。
    • 不允许read和load、store和write操作之一单独出现。
    • 不允许一个线程丢弃它的最近的assign操作,即变量在工作内存中改变了之后必须同步到主内存中。
    • 不允许一个线程无原因地(没有发生过任何assign操作)把数据从工作内存同步到主内存中。
    • 一个新的变量只能在主内存中诞生,不允许在工作内存中直接使用一个未被初始化(load或者assign)的变量。即就是对一个变量实施use和store操作之前必须先执行assgin和load操作。
    • 一个变量在同一时刻只允许一条线程对其进行lock操作,但lock操作可以被同一条线程重复执行多次,多次执行lock后,只有执行相同次数的unlock操作,变量才会被解锁。lock和unlock必须成对出现。
    • 如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要重新执行load或assign操作初始变化量的值。
    • 如果一个变量事先没有被lock锁定,则不允许对它执行unlock操作;也不允许去unlock一个被其他线程锁定的变量。
    • 对一个变量执行unlock操作之前,必须先把此变量同步到主内存中(执行store和write操作)。


    Java线程池

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.concurrent.LinkedBlockingQueue;
    
    public class MyThreadPool {
        //1.需要一个仓库
        private BlockingQueue<Runnable> blockingQueue;
    
        //2. 一个线程的集合
        private List<Thread> workers;
    
        //3. 一个人干活
        public static class Worker extends Thread {
            private MyThreadPool pool;
    
            public Worker(MyThreadPool pool) {
                this.pool = pool;
            }
    
            @Override
            public void run() {
                while (this.pool.isWorking || this.pool.blockingQueue.size() > 0) {
                    Runnable task = null;
    
                    try {
                        if(this.pool.isWorking)
                            task = this.pool.blockingQueue.take();
                        else
                            task = this.pool.blockingQueue.poll();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                    if (task != null) {
                        task.run();
                        System.out.println("线程:" + Thread.currentThread().getName() + "执行完毕");
                    }
                }
            }
        }
    
        //4.初始话线程池
        public MyThreadPool(int poolSize, int taskSize) {
            if (poolSize <= 0 || taskSize <= 0) {
                throw new IllegalArgumentException("非法参数");
            }
    
            this.blockingQueue = new LinkedBlockingQueue<>(taskSize);
            this.workers = Collections.synchronizedList(new ArrayList<>());
    
            for (int i = 0; i < poolSize; i++) {
                Worker worker = new Worker(this);
                worker.start();
                workers.add(worker);
            }
        }
    
        //5. 向仓库中放任务(非阻塞)
        public boolean submit(Runnable task) {
            if (isWorking) {
            return this.blockingQueue.offer(task);}
            return false;
        }
    
        //6.  向仓库中放任务(阻塞)
        public void execute(Runnable task) {
            if (isWorking){
                try {
                    this.blockingQueue.put(task);
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        //7. 关闭
        //关闭的时候,仓库停止有新的任务进来
        //关闭的时候,仓库如果还有东西要执行完毕
        //关闭的时候,如果再去仓库拿东西,就不能阻塞了
        //关闭的时候,如果还有线程被阻塞,要强行中断
        private volatile boolean isWorking = true;
    
        public void shutDown() {
            isWorking = false;
            for (Thread thread : workers) {
                if (thread.getState().equals(Thread.State.WAITING) ||
                        thread.getState().equals(Thread.State.BLOCKED)) {
                    thread.interrupt();
                }
            }
        }
    }
    

    未完待续。。。

    相关文章

      网友评论

          本文标题:Java并发编程

          本文链接:https://www.haomeiwen.com/subject/alklnqtx.html