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页开始

posted on 2018-10-26 16:54  匆匆而过  阅读(408)  评论(0编辑  收藏  举报

导航