同步类

(01) CountDownLatch的作用是允许1或N个线程等待其他线程完成执行;而CyclicBarrier则是允许N个线程相互等待。
(02) CountDownLatch的计数器无法被重置;CyclicBarrier的计数器可以被重置后使用,因此它被称为是循环的barrier。
关于CyclicBarrier的原理,后面一章再来学习。

CountDownLatch是通过“共享锁”实现的。在创建CountDownLatch中时,会传递一个int类型参数count,该参数是“锁计数器”的初始状态,表示该“共享锁”最多能被count给线程同时获取。当某线程调用该CountDownLatch对象的await()方法时,该线程会等待“共享锁”可用时,才能获取“共享锁”进而继续运行。而“共享锁”可用的条件,就是“锁计数器”的值为0!而“锁计数器”的初始值为count,每当一个线程调用该CountDownLatch对象的countDown()方法时,才将“锁计数器”-1;通过这种方式,必须有count个线程调用countDown()之后,“锁计数器”才为0,而前面提到的等待线程才能继续运行!

public class My {
    static CountDownLatch countDownLatch = new CountDownLatch(5);
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {
            for (int i = 0; i < 5; i++) {
                new MyT().start();
            }
            System.out.println(Thread.currentThread().getName() + "wait");
            countDownLatch.await();
            System.out.println(Thread.currentThread().getName() + "run");
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    static class MyT extends Thread {
        @Override
        public void run() {
            try {
                sleep(1000);
                System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");
                countDownLatch.countDown();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}

dowait()的作用就是让当前线程阻塞,直到“有parties个线程到达barrier” 或 “当前线程被中断” 或 “超时”这3者之一发生,当前线程才继续执行。

public class My {
    static CyclicBarrier barrier = new CyclicBarrier(5);
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            new MyT().start();
        }
        System.out.println(Thread.currentThread().getName() + "wait");
        System.out.println(Thread.currentThread().getName() + "run");

    }
    static class MyT extends Thread {
        @Override
        public void run() {
            try {
                sleep(1000);
                System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");
                barrier.await();
            } catch (Exception e) {
                // TODO: handle exception
            }
        }
    }
}
 

Semaphore是一个计数信号量,它的本质是一个"共享锁"。

信号量维护了一个信号量许可集。线程可以通过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;否则线程必须等待,直到有可用的许可为止。 线程可以通过release()来释放它所持有的信号量许可。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.Semaphore;

public class My {
    static CyclicBarrier barrier = new CyclicBarrier(5);
    public static void main(String[] args) {
        Semaphore sem = new Semaphore(10);
        new MyT(sem, 3).start();
        new MyT(sem, 5).start();
        new MyT(sem, 7).start();

    }
    static class MyT extends Thread {
        private volatile Semaphore sem;
        private int c;
        public MyT(Semaphore sem, int c) {
            this.sem = sem;
            this.c = c;
        }
        @Override
        public void run() {
            try {
                sem.acquire(c);
                System.out.println(Thread.currentThread().getName() + " sleep 1000ms.");
                Thread.sleep(1000);
            } catch (Exception e) {
                // TODO: handle exception
            }finally {
                sem.release(c);
            }
        }
    }
}
 

时间: 2024-10-03 14:15:01

同步类的相关文章

架构师养成--7.同步类容器和并发类容器

一.同步类容器 同步类容器都是线程安全的,但在某些场景下可能需要加锁来保护复合操作.复合类操作如:迭代(反复访问元素,遍历完容器中的所有元素).跳转(根据指定的顺序找到当前元素的下一个元素).以及条件运算.这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候并没有考虑并发修改的问题. 同步类容器:如古老的Vector/HashTable.

16.同步类容器Collections.synchronized

voctor动态数组.同步类容器,底层实现基于:Collections.synchronized package demo5; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Vector; /** * Created by liudan on 2017/7/9. */ public class MyThread2 extends Thread {

同步类容器和并发类容器

一.同步类容器 同步类容器都是线程安全的,但在某些场景下可能需要加锁来保护复合操作.复合类操作如:迭代(反复访问元素,遍历完容器中的所有元素).跳转(根据指定的顺序找到当前元素的下一个元素).以及条件运算.这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候并没有考虑并发修改的问题. 同步类容器:如古老的Vector/HashTable.

并发编程(9):同步类容器与并发类容器

1.同步类容器 同步类容器都是线程安全的,但在某些场景下可能需要加锁来保护复合操作. 复合操作,如: 迭代(反复访问元素,遍历完容器中所有的元素) 跳转(根据指定的顺序找到当前元素的下一个元素) 条件运算 这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为,最经典的就是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候并没有考虑并发修改的问题. 同步类容器:如古老的Vector.HashTble.这

线程学习--(七)单例和多线程、同步类容器和并发类容器

一.同步类容器 同步类容器都是线程安全的,但在某些场景下可能需要加锁来保护复合操作.复合类操作如:迭代(反复访问元素,遍历完容器中的所有元素).跳转(根据指定的顺序找到当前元素的下一个元素).以及条件运算.这些复合操作在多线程并发的修改容器时,可能会表现出意外的行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候并没有考虑并发修改的问题. 同步类容器:如古老的Vector/HashTable.

Java线程同步类容器和并发容器(四)

同步类容器都是线程安全的,在某些场景下,需要枷锁保护符合操作,最经典ConcurrentModifiicationException,原因是当容器迭代的过程中,被并发的修改了内容. for (Iterator iterator = tickets.iterator(); iterator.hasNext();) { String string = (String) iterator.next(); tickets.remove(20); } //多线程使用Vector或者HashTable的示例

解读java同步类CountDownLatch

同步辅助类: CountDownLatch是一个同步辅助类,在jdk5中引入,它允许一个或多个线程等待其他线程操作完成之后才执行. 实现原理 : CountDownLatch是通过计数器的方式来实现,计数器的初始值为线程的数量.每当一个线程完成了自己的任务之后,就会对计数器减1,当计数器的值为0时,表示所有线程完成了任务,此时等待在闭锁上的线程才继续执行,从而达到等待其他线程完成任务之后才继续执行的目的. CountDownLatch主要方法: CountDownLatch具体是通过同步器来实现

synchronized 线程同步-类级别锁定

1.demo 说明:代码中通过 printNum 方法传入参数判断 a.b 分别对 num 这个参数的值进行了修改. package demo1; import sun.applet.Main; public class MyThread2 extends Thread { private int num = 0; public synchronized void printNum(String str) { try { if (str.equals("a")) { num = 100

OGG运维优化脚本(十四)-信息同步类--定义文件自动下发

文件: resend.sh 路径:$HOME/ggscript/ggdef 功能:该脚本为用于应对目标端因为定义文件失效导致的进程异常中断所设计 因源端业务经常未通知目标端以及系统组自行修改表结构 因此设计该脚本自动生成定义文件,并发送至指定目标机器的相应路径,以用于目标机器REPLICATE进程的正常读取 日志路径:$HOME/gglog/ggupload #!/bin/bash cd $HOME if [ -f .profile ];then         . .profile fi if