• Think_in_java_4th(并发学习一)


    Java的并发是在顺序语言的基础上提供对线程的支持的。

    并发能够更加有效的执行我们的代码,也就是更加合理的应用CPU资源。

    并发程序往往CPU和内存使用率,要高于同等的非并发程序。

     下面就用Think_in_java_4th,并发这个章节中源码简单说一下自己的认识。

    LiftOff.java

    package concurrency;
    
    //: concurrency/LiftOff.java
    // Demonstration of the Runnable interface.
    
    public class LiftOff implements Runnable {
        protected int countDown = 10; // Default
        private static int taskCount = 0;
        private final int id = taskCount++;
    
        public LiftOff() {
        }
    
        public LiftOff(int countDown) {
            this.countDown = countDown;
        }
    
        public String status() {
            return "#" + id + "(" + (countDown > 0 ? countDown : "Liftoff!") + "), ";
        }
    
        public void run() {
            while (countDown-- > 0) {
                System.out.print(status());
                //线程调度器
                //将CPU从一个线程转移給另一个线程。
                Thread.yield();
            }
        }
    } /// :~

    MainThread.java

    package concurrency;
    
    //: concurrency/MainThread.java
    
    public class MainThread {
        public static void main(String[] args) {
            LiftOff launch = new LiftOff();
            launch.run();
        }
    } /*
       * Output: #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1),
       * #0(Liftoff!),
       */// :~

    MainThread的执行结果和我们不使用多线程基本上没有什么区别。

    package concurrency;
    
    //: concurrency/BasicThreads.java
    // The most basic use of the Thread class.
    
    public class BasicThreads {
        public static void main(String[] args) {
            Thread t = new Thread(new LiftOff());
            t.start();
            System.out.println("Waiting for LiftOff");
        }
    } /*
       * Output: (90% match) Waiting for LiftOff #0(9), #0(8), #0(7), #0(6), #0(5),
       * #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
       */// :~
    Thread 类使用后,我们可以看到。【"Waiting for LiftOff"】比【#0(9),...ff!),】更早被打印出来了。
    此时,CPU和内存的使用情况就初步体现出来了。
    new Thread的JDK源码。
    target(实现了Runnable的类)最终被给了一个新的tid(nextThreadID)之后,加入到ThreadGroup中。

    Thread
        public Thread(Runnable target) {
            init(null, target, "Thread-" + nextThreadNum(), 0);
        }
        private void init(ThreadGroup g, Runnable target, String name,
                          long stackSize, AccessControlContext acc) {
    。。。。。。
    g.addUnstarted();
    。。。。。。
    this.target = target; setPriority(priority); if (parent.inheritableThreadLocals != null) this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parent.inheritableThreadLocals); /* Stash the specified stack size in case the VM cares */ this.stackSize = stackSize; /* Set thread ID */ tid = nextThreadID(); }

     好了,我们大概知道new Thread 的过程了。此处应该有图,哈哈。偷个懒。

    也就是说,在【new Thread(new LiftOff())】被给予新的tid并加入到ThreadGroup的时候,System.out执行了。

    并且,System.out没有等待【t.start();】的执行完,再开始执行。

    这样的结果就是因为,主线程和子线程并发执行的结果。

    这时,【在顺序语言的基础上提供对线程的支持】句话就可以拿出来再理解一下了。

    Thread

     

        public synchronized void start() {
    ......
            /* Notify the group that this thread is about to be started
             * so that it can be added to the group's list of threads
             * and the group's unstarted count can be decremented. */
            group.add(this);
    ......
    }

     

    ThreadGroup

        void add(Thread t) {
    ......
                nUnstartedThreads--;
    ......
    }

    MoreBasicThreads.java

    package concurrency;
    
    //: concurrency/MoreBasicThreads.java
    // Adding more threads.
    
    public class MoreBasicThreads {
        public static void main(String[] args) {
            for (int i = 0; i < 5; i++)
                new Thread(new LiftOff()).start();
            System.out.println("Waiting for LiftOff");
        }
    } /*
       * Output: (Sample) Waiting for LiftOff #0(9), #1(9), #2(9), #3(9), #4(9),
       * #0(8), #1(8), #2(8), #3(8), #4(8), #0(7), #1(7), #2(7), #3(7), #4(7), #0(6),
       * #1(6), #2(6), #3(6), #4(6), #0(5), #1(5), #2(5), #3(5), #4(5), #0(4), #1(4),
       * #2(4), #3(4), #4(4), #0(3), #1(3), #2(3), #3(3), #4(3), #0(2), #1(2), #2(2),
       * #3(2), #4(2), #0(1), #1(1), #2(1), #3(1), #4(1), #0(Liftoff!), #1(Liftoff!),
       * #2(Liftoff!), #3(Liftoff!), #4(Liftoff!),
       */// :~
    #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #1(9), #2(9), #1(8), #0(2), #3(9), #1(7), Waiting for LiftOff
    #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(Liftoff!), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(Liftoff!), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(Liftoff!), #0(1), #4(9), #0(Liftoff!), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(Liftoff!), 

    创建多个线程,并启动。

    实际上,线程的创建销毁是非常快的。当一个线程完成了它的任务的时候,该线程占有的资源就会被释放。

    那么我们就又可以把已经释放的资源用于创建其他新的线程了。

    参考

    Java编程思想(第4版)    654页开始

    Thinking in Java(第四版 )  1116页开始

  • 相关阅读:
    orm 对象关系映射 指 表与类之间的映射 # 40
    事务 视图 触发器 函数 (内置) 存储过程 流程控制 索引 # 39
    exist 存在 Python操作mysql pymysql sql注入问题 # 38
    基本查询语句与方法 多表查询 # 37
    外键 #36
    存储引擎 索引 数据类型 约束条件 # 35
    mysql安装 登录 修改密码 库,表,记录(增删改查) # 34
    进程池和线程池 协程 # 33
    GIL全局解释器锁
    # 并发编程 -进程理论-进程的方法
  • 原文地址:https://www.cnblogs.com/danghyrz/p/9857373.html
Copyright © 2020-2023  润新知