• JAVA多线程(一)


    进程与线程:

    一个进程可以包含多个线程。多个线程可以并行,但是一个时间点只能有一个线程是运行状态。

    线程的状态:

    查看API可以,线程的状态分为五种:

    (JVM里面的状态:These states are virtual machine states which do not reflect any operating system thread states)

    1. NEW: 当新建一个Thread的时候,当前线程的处于新建状态,线程还未开始。

    2. RUNNABLE: 调用Thread的start方法,线程进入可运行状态,在这个状态下,线程开始处理工作,还有一种情况是未真正处理,还正在等待操作系统的调用。

    3. BLOCKED:  线程的阻塞状态。一种情况下当调用wait方法时,当前线程释放锁,其他线程获取锁,开始处理,当前线程进入阻塞状态。

    4. WAITING: 不定期等待状态。等待其他线程的notify.

    5. TIMED_WAITING:有一定期限的等待状态,与WAITING最明显的区别是Thread.sleep(). 可以指定sleep时间。

    6. TERMINATED: 终止状态。线程处理完成。

    两个JDK自带的同步工具类:CountDownLatch 和CyclicBarrier

    先上代码:

    package com.my.thread;
    
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class CountDownLatchTest {
    
        static CountDownLatch latch = new CountDownLatch(1);
        
        static CountDownLatch downLatch = new CountDownLatch(10);
        
        static ExecutorService service = Executors.newCachedThreadPool();
    
        public static void main(String[] args) {
            final long start = System.currentTimeMillis();
            
            for (int i = 0; i < 10; i++) {
                final int index = i+1;
                    Runnable runnable = new Runnable() {
                        
                        @Override
                        public void run() {
                            
                            try {
                                latch.await();
                                long end = System.currentTimeMillis();
                                System.out.println(Thread.currentThread().getName()+"===已鸣枪,第"+index+"位运动员出发,反应时间:"+(end-start)+"ms");
                                Thread.sleep((long) (Math.random() * 10000));
                                end = System.currentTimeMillis();
                                System.out.println(Thread.currentThread().getName()+"===第"+index+"位运动员完成,用时"+(end-start)+"ms");
                                downLatch.countDown();
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            
                        }
                    };
                    service.execute(runnable);
            }
            try {
                System.out.println("鸣枪开始!");
                latch.countDown();
                
                downLatch.await();
                System.out.println("比赛结束");
                
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            service.shutdown();
        }
        
        
    }

    CountDownLatchTest .java

    构造器中的计数值(count)实际上就是闭锁需要等待的线程数量。这个值只能被设置一次,而且CountDownLatch没有提供任何机制去重新设置这个计数值。

    与CountDownLatch的第一次交互是主线程等待其他线程。主线程必须在启动其他线程后立即调用CountDownLatch.await()方法。

    这样主线程的操作就会在这个方法上阻塞,直到其他线程完成各自的任务。

     1 package com.my.thread;
     2 
     3 import java.util.concurrent.BrokenBarrierException;
     4 import java.util.concurrent.CyclicBarrier;
     5 import java.util.concurrent.ExecutorService;
     6 import java.util.concurrent.Executors;
     7 
     8 public class ThreadCycleBarrire {
     9     public static void main(String[] args) {
    10         ExecutorService service = Executors.newCachedThreadPool();
    11         final CyclicBarrier cb = new CyclicBarrier(3); // 三个线程同时到达
    12         for (int i = 0; i < 3; i++) {
    13             Runnable runnable = new Runnable() {
    14                 public void run() {
    15                     try {
    16                 //        Thread.sleep((long) (Math.random() * 10000));
    17                         System.out.println(
    18                                 "线程" + Thread.currentThread().getName() + "即将到达集合地点1,当前已有" + (cb.getNumberWaiting() + 1)
    19                                         + "个已到达" + (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊" : "正在等候"));
    20                         try {
    21                             cb.await();
    22                         } catch (BrokenBarrierException e) {
    23                             // TODO Auto-generated catch block
    24                             e.printStackTrace();
    25                         }
    26                         Thread.sleep((long) (Math.random() * 10000));
    27                         System.out.println(
    28                                 "线程" + Thread.currentThread().getName() + "即将到达集合地点2,当前已有" + (cb.getNumberWaiting() + 1)
    29                                         + "个已到达" + (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊" : "正在等候"));
    30                         try {
    31                             cb.await();
    32                         } catch (BrokenBarrierException e) {
    33                             // TODO Auto-generated catch block
    34                             e.printStackTrace();
    35                         }
    36                         Thread.sleep((long) (Math.random() * 10000));
    37                         System.out.println(
    38                                 "线程" + Thread.currentThread().getName() + "即将到达集合地点3,当前已有" + (cb.getNumberWaiting() + 1)
    39                                         + "个已到达" + (cb.getNumberWaiting() == 2 ? "都到齐了,继续走啊" : "正在等候"));
    40                         try {
    41                             cb.await();
    42                         } catch (BrokenBarrierException e) {
    43                             // TODO Auto-generated catch block
    44                             e.printStackTrace();
    45                         }
    46                     } catch (InterruptedException e) {
    47                         // TODO Auto-generated catch block
    48                         e.printStackTrace();
    49                     }
    50                 }
    51             };
    52             service.execute(runnable);
    53         }
    54         service.shutdown();
    55     }
    56 }
    ThreadCycleBarrire.java

    CyclicBarrier 的字面意思是可循环使用(Cyclic)的屏障(Barrier)。它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。

    CyclicBarrier 可用于综合统计,用CyclicBarrier(int num,Runable run),最后运行run里面的方法。

  • 相关阅读:
    网络故障排除工具 | 快速定位网络故障
    Brocade博科光纤交换机zone配置
    博科Brocade 300光纤交换机配置zone教程
    游戏开发
    第8章 图
    第7章 二叉树
    第6章 树型结构
    第5章 递归
    第4章 字符串、数组和特殊矩阵
    第3章 顺序表的链式存储
  • 原文地址:https://www.cnblogs.com/liangblog/p/5807402.html
Copyright © 2020-2023  润新知