易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.2 基本的线程机制

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

  1. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)
  2. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.2 基本的线程机制/21.2.1 定义任务

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. //: concurrency/LiftOff.java

    // Demonstration of the Runnable interface.

    package concurrency;

    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();

        }

      }

    } ///:~

     

  2. //: concurrency/MainThread.java

    package concurrency;

    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!),

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.2 Thread类

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 单个线程:

    //: concurrency/BasicThreads.java

    // The most basic use of the Thread class.

    package concurrency;

    public class BasicThreads {

      public static void main(String[] args) {

       /**

        * 将多线程任务提交给  Thread

        */

        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!),

    *///:~

     

  2. 多个线程:

    //: concurrency/MoreBasicThreads.java

    // Adding more threads.

    package concurrency;

    public class MoreBasicThreads {

      public static void main(String[] args) {

       /**

        * 产生5个进程同时执行 

        */

        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!),

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.3 使用Executor(执行器)

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 概念:在客户端和任务执行之间提供一个间接层,由Executor直接执行任务,而不是客户端
  2. 高速缓存线程池:

    //: concurrency/CachedThreadPool.java

    package concurrency;

    import java.util.concurrent.*;

     

    public class CachedThreadPool {

      public static void main(String[] args) {

       /**

        *   newCachedThreadPool:高速缓存线程池

        */

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; i++)

          exec.execute(new LiftOff());

        exec.shutdown();

      }

    } /* Output: (Sample)

    #0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), #3(Liftoff!), #4(Liftoff!),

    *///:~

     

  3. 按数量申请线程池:

    //: concurrency/FixedThreadPool.java

    package concurrency;

    import java.util.concurrent.*;

     

    public class FixedThreadPool {

      public static void main(String[] args) {

        // Constructor argument is number of threads:

       /**

        * 申请5个线程资源 

        */

        ExecutorService exec = Executors.newFixedThreadPool(5);

        for(int i = 0; i < 5; i++)

          exec.execute(new LiftOff());

        exec.shutdown();

      }

    } /* Output: (Sample)

    #0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), #3(Liftoff!), #4(Liftoff!),

    *///:~

    易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

  4.  
  5. 申请单个线程:

    //: concurrency/SingleThreadExecutor.java

    package concurrency;

    import java.util.concurrent.*;

     

    public class SingleThreadExecutor {

      public static void main(String[] args) {

       /**

        * newSingleThreadExecutor:申请单个线程 

        */

        ExecutorService exec =

          Executors.newSingleThreadExecutor();

        for(int i = 0; i < 5; i++)

          exec.execute(new LiftOff());

        exec.shutdown();

      }

    } /* Output:

    #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(Liftoff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(Liftoff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(Liftoff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(Liftoff!),

    *///:~

    易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

    1. #0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!), #1(9), #1(8), #1(7), #1(6), #1(5), #1(4), #1(3), #1(2), #1(1), #1(Liftoff!), #2(9), #2(8), #2(7), #2(6), #2(5), #2(4), #2(3), #2(2), #2(1), #2(Liftoff!), #3(9), #3(8), #3(7), #3(6), #3(5), #3(4), #3(3), #3(2), #3(1), #3(Liftoff!), #4(9), #4(8), #4(7), #4(6), #4(5), #4(4), #4(3), #4(2), #4(1), #4(Liftoff!),


第21章 并发/21.2 基本的线程机制/21.2.4 从任务中产生返回值

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. //: concurrency/CallableDemo.java

    package concurrency;

    import java.util.concurrent.*;

    import java.util.*;

     

    class TaskWithResult implements Callable<String> {

      private int id;

      public TaskWithResult(int id) {

        this.id = id;

      }

      public String call() {

    // try {

    //    Thread.sleep(1000);

    // } catch (InterruptedException e) {

    //    /**

    //    * 当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。有时候,一种方法可能希望测试当前线程是否已被中断,如果已被中断,则立即抛出此异常。下列代码可以达到这种效果:

    // if (Thread.interrupted())  // Clears interrupted status!

    //      throw new InterruptedException();

    //

    //    */

    //    // TODO Auto-generated catch block

    //    e.printStackTrace();

    // }  

        return "result of TaskWithResult " + id;

      }

    }

     

    public class CallableDemo {

      public static void main(String[] args) {

       /**

        * 这里的  newCachedThreadPool   实现 Runnable是一样的

        */

        ExecutorService exec = Executors.newCachedThreadPool();

        /**

         * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,如有必要,计算完成前可以阻塞此方法。

         */

        ArrayList<Future<String>> results =

          new ArrayList<Future<String>>();

        for(int i = 0; i < 10; i++)

          /**

           * 1.Callable  Runnable不同的是,Runnable execute 进行调用,而 Callable submit 进行调用

           * 2.results保存计算结果

           */

          results.add(exec.submit(new TaskWithResult(i)));

        for(Future<String> fs : results)

          try {

            // get() blocks until completion:

           /**

            * 通过fs.get() 获取计算结果,如果没结束,则等待

            */

            System.out.println(fs.get());

          } catch(InterruptedException e) {

            System.out.println(e);

            return;

          } catch(ExecutionException e) {

            System.out.println(e);

          } finally {

            exec.shutdown();

          }

      }

    } /* Output:

    result of TaskWithResult 0

    result of TaskWithResult 1

    result of TaskWithResult 2

    result of TaskWithResult 3

    result of TaskWithResult 4

    result of TaskWithResult 5

    result of TaskWithResult 6

    result of TaskWithResult 7

    result of TaskWithResult 8

    result of TaskWithResult 9

    *///:~

    易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

  2. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.2 基本的线程机制/21.2.5 休眠

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)
  2. 重点代码:

     /**

           * NANOSECONDS:纳秒

           * MICROSECONDS:微妙

           * MILLISECONDS:毫秒

           * SECONDS:秒

           * 转换关系:

           * NANOSECONDS = 1/1000*MICROSECONDS

           * MICROSECONDS = 1/1000*MILLISECONDS

           * MILLISECONDS = 1/1000*SECONDS     

           */

          TimeUnit.MILLISECONDS.sleep(100);

     

  3.  

第21章 并发/21.2 基本的线程机制/21.2.6 优先级

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 概念:优先级将线程的重要性传递给调度器,使优先级高的线程先执行,优先级较低的线程后执行,但是高低线程都会执行,不会产生死锁

    //: concurrency/SimplePriorities.java

    // Shows the use of thread priorities.

    package concurrency;

    import java.util.concurrent.*;

     

    public class SimplePriorities implements Runnable {

      private int countDown = 5;

      /**

       * volatile:多线程相关  变量在同一个时间只能被一个线程访问

       */

      private volatile double d; // No optimization

      private int priority;

      public SimplePriorities(int priority) {

        this.priority = priority;

      }

      public String toString() {

       /**

        *  Thread.currentThread()打印结果:

        * Thread[pool-1-thread-6,10,main] 

        *

          1. pool-1:表示的池1

          2. thread-6:表示第6个线程

          3. 10:优先级

          4. main:线程发起方法

        */

        return Thread.currentThread() + ": " + countDown;

      }

      public void run() {

       /**

        * 设置线程优先级 

        */

        Thread.currentThread().setPriority(priority);

        while(true) {

          // An expensive, interruptable operation:

          for(int i = 1; i < 100000; i++) {

            d += (Math.PI + Math.E) / (double)i;

            if(i % 1000 == 0)

            /**

             * yield:建议相同优先级的线程可以执行,但是并不是强制  

             */

              Thread.yield();

          }

          /**

           * 调用方法 String toString() 打印当前线程

           */

          System.out.println(this);

          if(--countDown == 0) return;

        }

      }

      public static void main(String[] args) {

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; i++){

         /**

          * 初始化调用5个同级别线程

          */

          exec.execute(

            new SimplePriorities(Thread.MIN_PRIORITY));

        }

        /**

         * 再调用一个高级别线程

         */

        exec.execute(

            new SimplePriorities(Thread.MAX_PRIORITY));

        exec.shutdown();

      }

    } /* Output: (70% match)

    Thread[pool-1-thread-6,10,main]: 5

    Thread[pool-1-thread-6,10,main]: 4

    Thread[pool-1-thread-6,10,main]: 3

    Thread[pool-1-thread-6,10,main]: 2

    Thread[pool-1-thread-6,10,main]: 1

    Thread[pool-1-thread-3,1,main]: 5

    Thread[pool-1-thread-2,1,main]: 5

    Thread[pool-1-thread-1,1,main]: 5

    Thread[pool-1-thread-5,1,main]: 5

    Thread[pool-1-thread-4,1,main]: 5

    ...

    *///:~

     

    1. Thread.currentThread() 打印结果 Thread[pool-1-thread-6,10,main]
      1.  pool-1:表示的池1
      2. thread-6:表示第6个线程
      3. 10:优先级
      4. main:线程发起方法
    2. Thread[pool-1-thread-2,1,main]: 5

      Thread[pool-1-thread-6,10,main]: 5

      Thread[pool-1-thread-4,1,main]: 5

      Thread[pool-1-thread-3,1,main]: 5

      Thread[pool-1-thread-1,1,main]: 5

      Thread[pool-1-thread-5,1,main]: 5

      Thread[pool-1-thread-4,1,main]: 4

      Thread[pool-1-thread-2,1,main]: 4

      Thread[pool-1-thread-6,10,main]: 4

      Thread[pool-1-thread-4,1,main]: 3

      Thread[pool-1-thread-2,1,main]: 3

      Thread[pool-1-thread-3,1,main]: 4

      Thread[pool-1-thread-1,1,main]: 4

      Thread[pool-1-thread-5,1,main]: 4

      Thread[pool-1-thread-4,1,main]: 2

      Thread[pool-1-thread-2,1,main]: 2

      Thread[pool-1-thread-4,1,main]: 1

      Thread[pool-1-thread-6,10,main]: 3

      Thread[pool-1-thread-3,1,main]: 3

      Thread[pool-1-thread-2,1,main]: 1

      Thread[pool-1-thread-5,1,main]: 3

      Thread[pool-1-thread-1,1,main]: 3

      Thread[pool-1-thread-6,10,main]: 2

      Thread[pool-1-thread-3,1,main]: 2

      Thread[pool-1-thread-1,1,main]: 2

      Thread[pool-1-thread-5,1,main]: 2

      Thread[pool-1-thread-6,10,main]: 1

      Thread[pool-1-thread-3,1,main]: 1

      Thread[pool-1-thread-1,1,main]: 1

      Thread[pool-1-thread-5,1,main]: 1


第21章 并发/21.2 基本的线程机制/21.2.7 让步

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

  1. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.2 基本的线程机制/21.2.8 后台线程

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 概念:指的是程序结束后自动退出的线程
  2. //: concurrency/SimpleDaemons.java

    // Daemon threads don't prevent the program from ending.

    package concurrency;

    import java.util.concurrent.*;

    import static net.mindview.util.Print.*;

     

    public class SimpleDaemons implements Runnable {

      public void run() {

        try {

          /**

           * 这里是死循环,但是只要main函数执行完成后退出,则线程也自动结束 

           */

          while(true) {

            TimeUnit.MILLISECONDS.sleep(100);

            print(Thread.currentThread() + " " + this);

          }

        } catch(InterruptedException e) {

          print("sleep() interrupted");

        }

      }

      public static void main(String[] args) throws Exception {

        for(int i = 0; i < 10; i++) {

          Thread daemon = new Thread(new SimpleDaemons());

          /**

           * setDaemon:设置为后台线程,而且必须在star之前设置

           */

          daemon.setDaemon(true); // Must call before start()

          daemon.start();

        }

        print("All daemons started");

        TimeUnit.MILLISECONDS.sleep(100);

      }

    } /* Output: (Sample)

    All daemons started

    Thread[Thread-0,5,main] [email protected]

    Thread[Thread-1,5,main] [email protected]

    Thread[Thread-2,5,main] [email protected]

    Thread[Thread-3,5,main] [email protected]

    Thread[Thread-4,5,main] [email protected]

    Thread[Thread-5,5,main] [email protected]

    Thread[Thread-6,5,main] [email protected]

    Thread[Thread-7,5,main] [email protected]

    Thread[Thread-8,5,main] [email protected]

    Thread[Thread-9,5,main] [email protected]

    ...

    *///:~

     

  3. 工厂类后台进程:
    1. //: net/mindview/util/DaemonThreadFactory.java

      package net.mindview.util;

      import java.util.concurrent.*;

       

      public class DaemonThreadFactory implements ThreadFactory {

        public Thread newThread(Runnable r) {

          Thread t = new Thread(r);

          /**

           * 通过 DaemonThreadFactory 创建的所有线程都是 后台进程

           */

          t.setDaemon(true);

          return t;

        }

      } ///:~

       

    2. //: concurrency/DaemonFromFactory.java

      // Using a Thread Factory to create daemons.

      package concurrency;

      import java.util.concurrent.*;

      import net.mindview.util.*;

      import static net.mindview.util.Print.*;

       

      public class DaemonFromFactory implements Runnable {

        public void run() {

          try {

            while(true) {

              TimeUnit.MILLISECONDS.sleep(100);

              print(Thread.currentThread() + " " + this);

            }

          } catch(InterruptedException e) {

            print("Interrupted");

          }

        }

        public static void main(String[] args) throws Exception {

         /**

          * 这里的线程执行器  Executors 通过  线程工厂类进行初始化,

          * 由于 DaemonThreadFactory  的线程都是默认为后台线程,

          * 所以exec.execute执行的都是后台线程

           * 对于工厂类,先执行:ThreadFactory.public Thread newThread(Runnable r)

            * 再执行exec.execute

          */

          ExecutorService exec = Executors.newCachedThreadPool(

            new DaemonThreadFactory());

          for(int i = 0; i < 10; i++)

           /**

            * 1.执行创建操作,而且这个创建是基于DaemonThreadFactory

            * 2.执行DaemonFromFactory.run操作  

            */

            exec.execute(new DaemonFromFactory());

          print("All daemons started");

          TimeUnit.MILLISECONDS.sleep(100); // Run for a while

        }

      } /* (Execute to see output) *///:~

       

  4. 父线程为后台线程,那由它所创建的线程都默认是后台线程:

    //: concurrency/Daemons.java

    // Daemon threads spawn other daemon threads.

    package concurrency;

    import java.util.concurrent.*;

    import static net.mindview.util.Print.*;

     

    class Daemon implements Runnable {

      private Thread[] t = new Thread[10];

      public void run() {

        for(int i = 0; i < t.length; i++) {

         /**

          * 由于本线程为后台线程,所以它所创建的所有线程都是后台线程 

          */

          t[i] = new Thread(new DaemonSpawn());

          t[i].start();

          printnb("DaemonSpawn " + i + " started, ");

        }

        for(int i = 0; i < t.length; i++)

          printnb("t[" + i + "].isDaemon() = " +

            t[i].isDaemon() + ", ");

        while(true)

          Thread.yield();

      }

    }

     

    class DaemonSpawn implements Runnable {

      public void run() {

        while(true)

          Thread.yield();

      }

    }

     

    public class Daemons {

      public static void main(String[] args) throws Exception {

        Thread d = new Thread(new Daemon());

        /**

         * 将线程设置为后台进程,那么该线程所创建的其它线程自动设置为后台进程

         */

        d.setDaemon(true);

        d.start();

        printnb("d.isDaemon() = " + d.isDaemon() + ", ");

        // Allow the daemon threads to

        // finish their startup processes:

        TimeUnit.SECONDS.sleep(1);

      }

    } /* Output: (Sample)

    d.isDaemon() = true, DaemonSpawn 0 started, DaemonSpawn 1 started, DaemonSpawn 2 started, DaemonSpawn 3 started, DaemonSpawn 4 started, DaemonSpawn 5 started, DaemonSpawn 6 started, DaemonSpawn 7 started, DaemonSpawn 8 started, DaemonSpawn 9 started, t[0].isDaemon() = true, t[1].isDaemon() = true, t[2].isDaemon() = true, t[3].isDaemon() = true, t[4].isDaemon() = true, t[5].isDaemon() = true, t[6].isDaemon() = true, t[7].isDaemon() = true, t[8].isDaemon() = true, t[9].isDaemon() = true,

    *///:~

     

  5. 对于后台线程,finally子句也可能不会执行:

    //: concurrency/DaemonsDontRunFinally.java

    // Daemon threads don't run the finally clause

    package concurrency;

    import java.util.concurrent.*;

    import static net.mindview.util.Print.*;

     

    class ADaemon implements Runnable {

      public void run() {

        try {

          print("Starting ADaemon");

          TimeUnit.SECONDS.sleep(1);

        } catch(InterruptedException e) {

          print("Exiting via InterruptedException");

        } finally {

           /**

            * 这里的finally不一定会执行,因为main一旦退出,作为后台线程也会马上退出

            */

          print("This should always run?");

        }

      }

    }

     

    public class DaemonsDontRunFinally {

      public static void main(String[] args) throws Exception {

        Thread t = new Thread(new ADaemon());

        t.setDaemon(true);

        t.start();

        TimeUnit.SECONDS.sleep(1);

      }

    } /* Output:

    Starting ADaemon

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.9 编码的变体--内部类

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. Thread创建对象通过两种方式:
    1. name:线程名词
    2. new Runnable( )
  2. //: concurrency/ThreadVariations.java

    // Creating threads with inner classes.

    package concurrency;

    import java.util.concurrent.*;

    import static net.mindview.util.Print.*;

     

    // Using a named inner class:

    class InnerThread1 {

      private int countDown = 5;

      private Inner inner;

     

      /**

       * 显式内部类:Inner 实现 Thread

       * @author Administrator

       *

       */

      private class Inner extends Thread {

        Inner(String name) {

          super(name);

          start();

        }

        public void run() {

          try {

            while(true) {

              print(this);

              if(--countDown == 0) return;

              sleep(10);

            }

          } catch(InterruptedException e) {

            print("interrupted");

          }

        }

        public String toString() {

          return getName() + ": " + countDown;

        }

      }

      public InnerThread1(String name) {

        inner = new Inner(name);

      }

    }

     

    // Using an anonymous inner class:

    class InnerThread2 {

      private int countDown = 5;

      private Thread t;

      public InnerThread2(String name) {

       /**

        * 隐式内部类 :Thread

        */

        t = new Thread(name) {

          public void run() {

            try {

              while(true) {

                print(this);

                if(--countDown == 0) return;

                sleep(10);

              }

            } catch(InterruptedException e) {

              print("sleep() interrupted");

            }

          }

          public String toString() {

            return getName() + ": " + countDown;

          }

        };

        t.start();

      }

    }

     

    // Using a named Runnable implementation:

    class InnerRunnable1 {

      private int countDown = 5;

      private Inner inner;

      /**

       * 显式内部类:Inner 实现 Runnable

       * @author Administrator

       *

       */

      private class Inner implements Runnable {

        Thread t;

        Inner(String name) {

          t = new Thread(this, name);

          t.start();

        }

        public void run() {

          try {

            while(true) {

              print(this);

              if(--countDown == 0) return;

              TimeUnit.MILLISECONDS.sleep(10);

            }

          } catch(InterruptedException e) {

            print("sleep() interrupted");

          }

        }

        public String toString() {

          return t.getName() + ": " + countDown;

        }

      }

      public InnerRunnable1(String name) {

        inner = new Inner(name);

      }

    }

     

    // Using an anonymous Runnable implementation:

    class InnerRunnable2 {

      private int countDown = 5;

      private Thread t;

      public InnerRunnable2(String name) {

       /**

        *  隐式内部类:通过 new Runnable()实现

        */

        t = new Thread(new Runnable() {

          public void run() {

            try {

              while(true) {

                print(this);

                if(--countDown == 0) return;

                TimeUnit.MILLISECONDS.sleep(10);

              }

            } catch(InterruptedException e) {

              print("sleep() interrupted");

            }

          }

          public String toString() {

            return Thread.currentThread().getName() +

              ": " + countDown;

          }

        }, name);

        t.start();

      }

    }

     

    // A separate method to run some code as a task:

    class ThreadMethod {

      private int countDown = 5;

      private Thread t;

      private String name;

      public ThreadMethod(String name) { this.name = name; }

      public void runTask() {

        if(t == null) {

          /**

           * 隐式内部类 

           */

          t = new Thread(name) {

            public void run() {

              try {

                while(true) {

                  print(this);

                  if(--countDown == 0) return;

                  sleep(10);

                }

              } catch(InterruptedException e) {

                print("sleep() interrupted");

              }

            }

            public String toString() {

              return getName() + ": " + countDown;

            }

          };

          t.start();

        }

      }

    }

     

    public class ThreadVariations {

      public static void main(String[] args) {

        new InnerThread1("InnerThread1");

        new InnerThread2("InnerThread2");

        new InnerRunnable1("InnerRunnable1");

        new InnerRunnable2("InnerRunnable2");

        new ThreadMethod("ThreadMethod").runTask();

      }

    } /* (Execute to see output) *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.9 编码的变体--直接继承Thread

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 直接从Thread类继承实现多线程:易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.2 基本的线程机制/21.2.11 加入一个线程

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. join用于在其它线程之上执行某个线程,其它线程要在这个线程执行完成后才能接着执行
  2. join可以带超时参数,超过该时间后,无论线程是否结束都返回
  3. 也可以调用interrupt方法中断join发起的线程
  4. //: concurrency/SimpleThread.java

    // Inheriting directly from the Thread class.

    package concurrency;

    public class SimpleThread extends Thread {

      private int countDown = 5;

      private static int threadCount = 0;

      public SimpleThread() {

        // Store the thread name:

       /*

        * 定义线程名词 

        */

        super(Integer.toString(++threadCount));

        start();

      }

      public String toString() {

        /**

         * getName:获取线程名词

         */

        return "#" + getName() + "(" + countDown + "), ";

      }

      public void run() {

        while(true) {

          System.out.print(this);

          if(--countDown == 0)

            return;

        }

      }

      public static void main(String[] args) {

        for(int i = 0; i < 5; i++)

          new SimpleThread();

      }

    } /* Output:

    #1(5), #1(4), #1(3), #1(2), #1(1), #2(5), #2(4), #2(3), #2(2), #2(1), #3(5), #3(4), #3(3), #3(2), #3(1), #4(5), #4(4), #4(3), #4(2), #4(1), #5(5), #5(4), #5(3), #5(2), #5(1),

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.12 创建有响应的用户界面

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. //: concurrency/Joining.java

    // Understanding join().

    package concurrency;

    import static net.mindview.util.Print.*;

     

    class Sleeper extends Thread {

      private int duration;

      public Sleeper(String name, int sleepTime) {

        super(name);

        duration = sleepTime;

        start();

      }

      public void run() {

        try {

          sleep(duration);

        } catch(InterruptedException e) {

        /*

         * 休眠期间被中断抛出本异常

         */

          print(getName() + " was interrupted. " +

            "isInterrupted(): " + isInterrupted());

          return;

        }

        print(getName() + " has awakened");

      }

    }

     

    class Joiner extends Thread {

      private Sleeper sleeper;

      public Joiner(String name, Sleeper sleeper) {

        super(name);

        this.sleeper = sleeper;

        start();

      }

      public void run() {

       try {

         /**

          *sleeper线程在this线程之上执行,这个时候this线程将被挂起

          *因为sleeper进程处于睡眠状态,所以this要等待sleeper结束后再执行

          */

          sleeper.join();

          System.out.println(getName()+":Joiner.join");

        } catch(InterruptedException e) {

          print("this.Interrupted");

        }

        print(getName() + " join completed");

      }

    }

     

    public class Joining {

      public static void main(String[] args) {

        Sleeper

          sleepy = new Sleeper("Sleepy", 1500),

          grumpy = new Sleeper("Grumpy", 1500);

        Joiner

          dopey = new Joiner("Dopey", sleepy),

          doc = new Joiner("Doc", grumpy);

        /**

         * interrupt:中断 grumpy线程,由于grumpy被中断,所以doc能得到立刻执行

         */

        grumpy.interrupt();

      }

    } /* Output:

    Grumpy was interrupted. isInterrupted(): false

    Doc join completed

    Sleepy has awakened

    Dopey join completed

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.13 线程组

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

  1. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

    易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

     


第21章 并发/21.2 基本的线程机制/21.2.14 捕捉异常-1.使用特定未能捕捉的异常

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 实现未能捕捉的异常:

    class MyUncaughtExceptionHandler implements

    Thread.UncaughtExceptionHandler {

      public void uncaughtException(Thread t, Throwable e) {

        System.out.println("caught " + e);

      }

    }

  2. //: concurrency/CaptureUncaughtException.java

    package concurrency;

    import java.util.concurrent.*;

     

    class ExceptionThread2 implements Runnable {

      public void run() {

        Thread t = Thread.currentThread();

        System.out.println("run() by " + t);

        System.out.println(

         /**

          * getUncaughtExceptionHandler:返回该线程由于未捕获到异常而突然终止时调用的处理程序     

          */

          "eh2222 = " + t.getUncaughtExceptionHandler());

        throw new RuntimeException();

      }

    }

     

    class MyUncaughtExceptionHandler implements

    Thread.UncaughtExceptionHandler {

      public void uncaughtException(Thread t, Throwable e) {

        System.out.println("caught " + e);

      }

    }

     

    /**

     * 实现线程工厂类

     * @author Administrator

     *

     */

    class HandlerThreadFactory implements ThreadFactory {

      public Thread newThread(Runnable r) {

        System.out.println(this + " creating new Thread");

        Thread t = new Thread(r);

        System.out.println("created " + t);

        /**

         * 设置未捕捉错误

         */

        t.setUncaughtExceptionHandler(

          new MyUncaughtExceptionHandler());

        /**

         * 打印未捕捉错误

         */

        System.out.println(

          "eh111 = " + t.getUncaughtExceptionHandler());

        return t;

      }

    }

     

    public class CaptureUncaughtException {

      public static void main(String[] args) {

        ExecutorService exec = Executors.newCachedThreadPool(

          new HandlerThreadFactory());

        exec.execute(new ExceptionThread2());

      }

    } /* Output: (90% match)

    [email protected] creating new Thread

    created Thread[Thread-0,5,main]

    eh = [email protected]

    run() by Thread[Thread-0,5,main]

    eh = [email protected]

    caught java.lang.RuntimeException

    *///:~

     


第21章 并发/21.2 基本的线程机制/21.2.14 捕捉异常-2.使用默认捕捉未能异常

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

  • 捕捉异常-2.使用默认捕捉未能异常:

    //: concurrency/ExceptionThread.java

    // {ThrowsException}

    package concurrency;

    import java.util.concurrent.*;

     

    public class ExceptionThread implements Runnable {

      public void run() {

        throw new RuntimeException();

      }

      public static void main(String[] args) {

        ExecutorService exec = Executors.newCachedThreadPool();

        exec.execute(new ExceptionThread());

      }

    } ///:~

     


第21章 并发/21.3 共享受限资源

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

  1. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.3 共享受限资源/21.3.1 不正确地访问资源

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. //: concurrency/IntGenerator.java

    package concurrency;

    public abstract class IntGenerator {

      private volatile boolean canceled = false;

      public abstract int next();

      // Allow this to be canceled:

      public void cancel() { canceled = true; }

      public boolean isCanceled() { return canceled; }

    } ///:~

     

  2. //: concurrency/EvenChecker.java

    package concurrency;

    import java.util.concurrent.*;

     

    /**

     * EvenChecker:事件消费者

     * @author Administrator

     *

     */

    public class EvenChecker implements Runnable {

      private IntGenerator generator;

      private final int id;

      public EvenChecker(IntGenerator g, int ident) {

        generator = g;

        id = ident;

      }

      public void run() {

        while(!generator.isCanceled()) {

          int val = generator.next();

          if(val % 2 != 0) {

            System.out.println(val + " not even!");

            generator.cancel(); // Cancels all EvenCheckers

          }

        }

      }

      // Test any type of IntGenerator:

      public static void test(IntGenerator gp, int count) {

        System.out.println("Press Control-C to exit");

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < count; i++)

          exec.execute(new EvenChecker(gp, i));

        exec.shutdown();

      }

      // Default value for count:

      public static void test(IntGenerator gp) {

        test(gp, 10);

      }

    } ///:~

     

  3. //: concurrency/EvenGenerator.java

    // When threads collide.

    package concurrency;

     

    /**

     * @author Administrator

     *

     */

    public class EvenGenerator extends IntGenerator {

      private int currentEvenValue = 0;

      /**

       *  currentEvenValue 只由一个对象持有的,但是 next 会被多个线程调用,也就是 currentEvenValue 属于多个线程的,那么currentEvenValue可能同时被多个线程修改

       *  所有不能保证每次next方法后都是偶数

       */

      public  int next() {

        ++currentEvenValue; // Danger point here!

        ++currentEvenValue;

        return currentEvenValue;

      }

      public static void main(String[] args) {

        EvenChecker.test(new EvenGenerator());

      }

    } /* Output: (Sample)

    Press Control-C to exit

    89476993 not even!

    89476993 not even!

    *///:~

     

    /**
    1.    *  currentEvenValue 只由一个对象持有的,但是 next 会被多个线程调用,也就是 currentEvenValue 属于多个线程的,那么currentEvenValue可能同时被多个线程修改

         *  所有不能保证每次next方法后都是偶数

         */

        public  int next() {

          ++currentEvenValue// Danger point here!

          ++currentEvenValue;

          return currentEvenValue;

        }


第21章 并发/21.3 共享受限资源/21.3.2 解决资源共享竞争--1.synchronized

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. synchronized:限制每次只能由一个线程调用

    1. //: concurrency/SynchronizedEvenGenerator.java

      // Simplifying mutexes with the synchronized keyword.

      // {RunByHand}

      package concurrency;

      public class

      SynchronizedEvenGenerator extends IntGenerator {

        private int currentEvenValue = 0;

        public synchronized int next() {

          ++currentEvenValue;

          Thread.yield(); // Cause failure faster

          ++currentEvenValue;

          return currentEvenValue;

        }

        public static void main(String[] args) {

          EvenChecker.test(new SynchronizedEvenGenerator());

        }

      } ///:~

       

    2. 其它代码参照: 第21章 并发/21.3 共享受限资源/21.3.1 不正确地访问资源
  2.  

第21章 并发/21.3 共享受限资源/21.3.2 解决资源共享竞争--2.使用锁Lock

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. //: concurrency/MutexEvenGenerator.java

    // Preventing thread collisions with mutexes.

    // {RunByHand}

    package concurrency;

    import java.util.concurrent.locks.*;

     

    public class MutexEvenGenerator extends IntGenerator {

      private int currentEvenValue = 0;

      private Lock lock = new ReentrantLock();

      public int next() {

       /**

        * 使用   lock 锁定 try部分内容,而且try中必须出现return,防止过早执行unlock

        */

        lock.lock();

        try {

          ++currentEvenValue;

          Thread.yield(); // Cause failure faster

          ++currentEvenValue;

          return currentEvenValue;

        } finally {

          /**

           * 不管怎么样,必须进行解锁操作

           */

          lock.unlock();

        }

      }

      public static void main(String[] args) {

        EvenChecker.test(new MutexEvenGenerator());

      }

    } ///:~

    易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

  2. 易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)

第21章 并发/21.3 共享受限资源/21.3.3 原子性和易变性

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. volatile
    1. 用 volatile 修改的域:保证修改马上生效
    2. 用volatile而不用synchronized唯一情况是:类中只有一个可变域易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)
  2. 错误的原子性:

    //: concurrency/AtomicityTest.java

    package concurrency;

    import java.util.concurrent.*;

     

    public class AtomicityTest implements Runnable {

      private  int i = 0;

      public synchronized int getValue() { return i; }

      private synchronized void evenIncrement() {

         i++;

         i++;

         System.out.println("写入:"+i);

         }

      public void run() {

        while(true){

          evenIncrement();

          try {

          TimeUnit.SECONDS.sleep(10);

       } catch (InterruptedException e) {

          // TODO Auto-generated catch block

          e.printStackTrace();

       }

        }

      }

      public static void main(String[] args) {

        ExecutorService exec = Executors.newCachedThreadPool();

        AtomicityTest at = new AtomicityTest();

        exec.execute(at);

        while(true) {

          /**

           * getValue()可能取到了中间过程的值, 也就是evenIncrement有两次i++,当执行完第一个i++后该值就被getValue取到

           * 那如何保障getValue能取到正确的值呢?

           * getValue:也要加上 synchronized,synchronized 保障 方法对同一个变量的读写原子性

           */

          int val = at.getValue();

          System.out.println("读取:"+val);

          if(val % 2 != 0) {

            System.out.println(val);

            System.exit(0);

          }

        }

      }

    } /* Output: (Sample)

    191583767

    *///:~

     

    public static void main(String[] args) {

        ExecutorService exec = Executors.newCachedThreadPool();

        AtomicityTest at = new AtomicityTest();

        exec.execute(at);

        while(true) {

          /**

           * getValue()可能取到了中间过程的值,  也就是evenIncrement有两次i++,当执行完第一个i++后该值就被getValue取到

           * 那如何保障getValue能取到正确的值呢?

           * getValue:也要加上 synchronized,synchronized 保障 方法对同一个变量的读写原子性

           */

          int val = at.getValue();

          System.out.println("读取:"+val);

          if(val % 2 != 0) {

            System.out.println(val);

            System.exit(0);

          }

        }

      }


第21章 并发/21.3 共享受限资源/21.3.4 原子类

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. AtomicInteger :正数原子类
  2. AtomicLong :正数原子类
  3. AtomicReference::引用原子类
  4. 用AtomicIntegerTest代替AtomicityTest( 第21章 并发/21.3 共享受限资源/21.3.3 原子性和易变性

    //: concurrency/AtomicIntegerTest.java

    package concurrency;

    import java.util.concurrent.*;

    import java.util.concurrent.atomic.*;

    import java.util.*;

     

    public class AtomicIntegerTest implements Runnable {

      /**

       * AtomicInteger:原子类,用来保证原子性的,所有这里的

       * getValue   evenIncrement 没有必要加 synchronized

       */

      private AtomicInteger i = new AtomicInteger(0);

      public int getValue() { return i.get(); }

      private void evenIncrement() { i.addAndGet(2); }

      public void run() {

        while(true)

          evenIncrement();

      }

      public static void main(String[] args) {

        new Timer().schedule(new TimerTask() {

          public void run() {

            System.err.println("Aborting");

            System.exit(0);

          }

        }, 5000); // Terminate after 5 seconds

        ExecutorService exec = Executors.newCachedThreadPool();

        AtomicIntegerTest ait = new AtomicIntegerTest();

        exec.execute(ait);

        while(true) {

          int val = ait.getValue();

          if(val % 2 != 0) {

            System.out.println(val);

            System.exit(0);

          }

        }

      }

    } ///:~

     


第21章 并发/21.3 共享受限资源/21.3.5 临界区-用synchronized修饰部分代码,而不是整个方法

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 格式:易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--第21章 并发(一)
  2. 锁的范围:整个方法锁比模块锁慢
  3. 锁的作用:共享变量被一个线程锁住时,其它线程就会被阻塞
  4. //: concurrency/CriticalSection.java

    // Synchronizing blocks instead of entire methods. Also

    // demonstrates protection of a non-thread-safe class

    // with a thread-safe one.

    package concurrency;

    import java.util.concurrent.*;

    import java.util.concurrent.atomic.*;

    import java.util.*;

     

    /**

     * 坐标类:主要用来检查XY坐标值是否相等

     * @author Administrator

     *

     */

    class Pair { // Not thread-safe

      private int x, y;

      public Pair(int x, int y) {

        this.x = x;

        this.y = y;

      }

      public Pair() { this(0, 0); }

      public int getX() { return x; }

      public int getY() { return y; }

      public void incrementX() { x++; }

      public void incrementY() { y++; }

      public String toString() {

        return "x: " + x + ", y: " + y;

      }

      public class PairValuesNotEqualException extends RuntimeException {

        public PairValuesNotEqualException() {

          super("Pair values not equal: " + Pair.this);

        }

      }

      // Arbitrary invariant -- both variables must be equal:

      /**

       * 如果两个坐标值不相等则抛出异常

       */

      public void checkState() {

        if(x != y)

          throw new PairValuesNotEqualException();

      }

    }

     

    // Protect a Pair inside a thread-safe class:

    abstract class PairManager {

      AtomicInteger checkCounter = new AtomicInteger(0);

      protected Pair p = new Pair();

      private List<Pair> storage =

        Collections.synchronizedList(new ArrayList<Pair>());

      public synchronized Pair getPair() {

        // Make a copy to keep the original safe:

        return new Pair(p.getX(), p.getY());

      }

      // Assume this is a time consuming operation

      protected void store(Pair p) {

        storage.add(p);

        try {

          TimeUnit.MILLISECONDS.sleep(50);

        } catch(InterruptedException ignore) {}

      }

     

      public String toString(){

        String strResult=  String.format("X=%d, Y=%d",p.getX(), p.getY());

        return strResult;

      }

     

      public abstract void increment();

     

    }

     

    // Synchronize the entire method:

    class PairManager1 extends PairManager {

       /**

        * 这里的synchronized针对整个方法,锁定的时间比较长

        */

      public synchronized void increment() {

        p.incrementX();

        p.incrementY();

        store(getPair());

        /**

         * 通过 TimeUnit.SECONDS.sleep(10); 休眠操作可以测试锁的作用,共享变量被一个线程锁住时,其它线程就会被阻塞

         */

    //    try {

    //    TimeUnit.SECONDS.sleep(10);

    // } catch (InterruptedException e) {

    //    // TODO Auto-generated catch block

    //    e.printStackTrace();

    // }

      }

     

    }

     

    // Use a critical section:

    class PairManager2 extends PairManager {

      public void increment() {

        Pair temp;

        /**

         * synchronized:线程块控制:锁定的时间相对于整个方法锁定来说,锁定的时间稍微短点

         */

        synchronized(this) {

          p.incrementX();

          p.incrementY();

          temp = getPair();

          /**

           * 通过 TimeUnit.SECONDS.sleep(10); 休眠操作可以测试锁的作用,共享变量被一个线程锁住时,其它线程就会被阻塞

           */

    //      try {

    //        TimeUnit.SECONDS.sleep(10);

    //    } catch (InterruptedException e) {

    //        // TODO Auto-generated catch block

    //        e.printStackTrace();

    //    }

        }

        store(temp);

      }

     

    }

     

    /**

     * PairManipulator:创建线程方式

     * run逻辑:

     * 1.自增XY

     * 2.通过整个方法锁定或者代码块锁定两种方式

     * @author Administrator

     *

     */

    class PairManipulator implements Runnable {

      private PairManager pm;

      public PairManipulator(PairManager pm) {

        this.pm = pm;

      }

      public void run() {

        while(true)

          pm.increment();

      }

      public String toString() {

       /**

        * pm.getPair():获取XY的值 

        * pm.checkCounter.get():获取 AtomicInteger类的值

        */

        return "Pair: " + pm.getPair() +

          " checkCounter = " + pm.checkCounter.get();

      }

    }

     

    /**

     * PairChecker:创建线程方式

     * run逻辑:

     * 1.使用原子类方式实现checkCounter自增

     * 2.通过getPair获取XY的值

     * @author Administrator

     *

     */

    class PairChecker implements Runnable {

      private PairManager pm;

      public PairChecker(PairManager pm) {

        this.pm = pm;

      }

      public void run() {

        while(true) {

          /**

           * pm.checkCounter.incrementAndGet(): AtomicInteger类新增并且或者新值

           */

          pm.checkCounter.incrementAndGet();

          pm.getPair().checkState();

          System.out.println(pm);

        }

      }

     

    }

     

    public class CriticalSection {

      // Test the two different approaches:

      static void

      testApproaches(PairManager pman1, PairManager pman2) {

        ExecutorService exec = Executors.newCachedThreadPool();

        /**

         * PairManipulator:自增XY

         */

        PairManipulator

          pm1 = new PairManipulator(pman1),

          pm2 = new PairManipulator(pman2);

        /**

         * PairChecker:自增原子类checkCounter

         */

        PairChecker

          pcheck1 = new PairChecker(pman1),

          pcheck2 = new PairChecker(pman2);

        exec.execute(pm1);

        exec.execute(pm2);

        exec.execute(pcheck1);

        exec.execute(pcheck2);

        try {

          /**

           * NANOSECONDS:纳秒

           * MICROSECONDS:微妙

           * MILLISECONDS:毫秒

           * SECONDS:

           * 转换关系:

           * NANOSECONDS = 1/1000*MICROSECONDS

           * MICROSECONDS = 1/1000*MILLISECONDS

           * MILLISECONDS = 1/1000*SECONDS  

           */

          TimeUnit.MILLISECONDS.sleep(500);

        } catch(InterruptedException e) {

          System.out.println("Sleep interrupted");

        }

        System.out.println("pm1: " + pm1 + "\npm2: " + pm2);

        System.exit(0);

      }

      public static void main(String[] args) {

        PairManager

          pman1 = new PairManager1(),

          pman2 = new PairManager2();

        /**

         * pman1:代表整个方法方式锁定线程

         * pman2:代表代码块锁定线程

         */

        testApproaches(pman1, pman2);

      }

    } /* Output: (Sample)

    pm1: Pair: x: 15, y: 15 checkCounter = 272565

    pm2: Pair: x: 16, y: 16 checkCounter = 3956974

    *///:~

     


第21章 并发/21.3 共享受限资源/21.3.6 在其它对象上同步--不同对象的锁

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 同一个对象的锁,在同一个时间只能执行一段逻辑,完成后才释放给其它锁逻辑,例如: 第21章 并发/21.3 共享受限资源/21.3.3 原子性和易变性  中的 synchronized int getValue 与  synchronized void evenIncrement()  是互斥的
  2. 不同对象的锁相互独立,例如本例子

    //: concurrency/SyncObject.java

    // Synchronizing on another object.

    package concurrency;

    import static net.mindview.util.Print.*;

     

    import java.util.concurrent.TimeUnit;

     

    class DualSynch {

      private Object syncObject = new Object();

      /**

       * f:使用方法锁

       */

      public synchronized void f() {

        for(int i = 0; i < 5; i++) {

          print("f()");

          Thread.yield();

          try {

          TimeUnit.SECONDS.sleep(5);

       } catch (InterruptedException e) {

          // TODO Auto-generated catch block

          e.printStackTrace();

       }

        }

      }

      public void g() {

       /**

        * g:使用代码块锁,而且对象为  syncObject,这个锁与f()synchronized锁是相互独立,因为他们是不同对象的锁

        * 如果synchronized(this)换成synchronized(this),则与f()synchronized锁是相同的,两者就是互斥,再同一个时间只能使用一个

        */

        synchronized(syncObject) {

          for(int i = 0; i < 5; i++) {

            print("g()");

            Thread.yield();

            try {

              TimeUnit.SECONDS.sleep(10);

           } catch (InterruptedException e) {

              // TODO Auto-generated catch block

              e.printStackTrace();

           }

          }

        }

      }

    }

     

    public class SyncObject {

      public static void main(String[] args) {

        final DualSynch ds = new DualSynch();

        new Thread() {

          public void run() {

            ds.f();

          }

        }.start();

        ds.g();

      }

    } /* Output: (Sample)

    g()

    f()

    g()

    f()

    g()

    f()

    g()

    f()

    g()

    f()

    *///:~

     


第21章 并发/21.3 共享受限资源/21.3.7 线程本地存储

标签: 作者:易学笔记  更多资料请联系微信或QQ:1776565180

 

 

 

  1. 概念:对每一个线程所操作的变量X都进行本地存储,使得每一个线程和当时的变量值进行关联。
  2. 目的:防止共享资源产生冲突的第二种方法是根除对变量的共享,那就是线程本地存储。
  3. //: concurrency/ThreadLocalVariableHolder.java

    // Automatically giving each thread its own storage.

    package concurrency;

    import java.util.concurrent.*;

    import java.util.*;

     

    class Accessor implements Runnable {

     /**

      * 线程ID  

      */

      private final int id;

      public Accessor(int idn) { id = idn; }

      public void run() {

        while(!Thread.currentThread().isInterrupted()) {

         /**

          * ThreadLocalVariableHolder:本地存储对象新增操作

          */

          ThreadLocalVariableHolder.increment();

          System.out.println(this);

          Thread.yield();

        }

      }

      public String toString() {

        return "#" + id + ": " +

          ThreadLocalVariableHolder.get();

      }

    }

     

    public class ThreadLocalVariableHolder {

      /**

       * 创建匿名内部类继承于ThreadLocal

       */

      private static ThreadLocal<Integer> value =

        new ThreadLocal<Integer>() {

          private Random rand = new Random(47);

          protected synchronized Integer initialValue() {

            return rand.nextInt(10000);

          }

        };

      public static void increment() {

        value.set(value.get() + 1);

      }

      public static int get() { return value.get(); }

      public static void main(String[] args) throws Exception {

        ExecutorService exec = Executors.newCachedThreadPool();

        for(int i = 0; i < 5; i++)

          exec.execute(new Accessor(i));

        TimeUnit.SECONDS.sleep(3);  // Run for a while

        exec.shutdownNow();         // All Accessors will quit

      }

    } /* Output: (Sample)

    #0: 9259

    #1: 556

    #2: 6694

    #3: 1862

    #4: 962

    #0: 9260

    #1: 557

    #2: 6695

    #3: 1863

    #4: 963

    ...

    *///:~

     

    1. public class ThreadLocalVariableHolder {

        /**

         * 创建匿名内部类继承于ThreadLocal    

         */

        private static ThreadLocal<Integer> value =

          new ThreadLocal<Integer>() {

            private Random rand = new Random(47);

            protected synchronized Integer initialValue() {

              return rand.nextInt(10000);

            }

          };

        public static void increment() {

          value.set(value.get() + 1);

        }

        public static int get() { return value.get(); }

        public static void main(String[] args) throws Exception {

          ExecutorService exec = Executors.newCachedThreadPool();

          for(int i = 0; i < 5; i++)

            exec.execute(new Accessor(i));

          TimeUnit.SECONDS.sleep(3);  // Run for a while

          exec.shutdownNow();         // All Accessors will quit

        }

      》》》》》未完:易学笔记--从0开始学JAVA(个人纯手工笔记共享 免费!免费!免费!)--比直接看书快N倍的速度掌握知识点--总共19章》》》》》