多线程--04

线程安全的类:

Vector与ArrayList:

    实现的原理都是通过数组实现的,查询速度比较快,增加,删除修改的速度比较慢。数组的增加和删除需要涉及到数据的copy。所以速度会慢一些。
    区别:
        Vector是线程安全的,方法使用synchronized关键字,使用同步函数来保证线程的安全。
        ArrayList是线程不安全,但是效率是比较高的
        LinkedList 是线程不安全的,增加和修改的速度比较快,查询的速度比较慢。

HashTable与HashMap的区别:

HashTable 是线程安全的,方法使用synchronized 关键字修饰,效率非常低,存在锁的竞争资源。
HashMap 是线程不安全的,是通过链表加数组的方式实现的。

ConcurrentHashMap–分段式锁。

    分段原理:讲一个整体拆分成小的hashTable。默认分成16段。
ConcurrentHashMap:  内部使用段来表示这些不同的部分,每一段
    其实就是一个小的HashTable,他们都有自己锁,只要多个修改操作发生在不同的段上,他们就可以并发执行进行。把一个整体分成16段,(也就是最高支持16个线程并发执行。)这也是在重线程场景中减少锁的粒度,从而降低锁竞争的一种方案,。并且在代码中大多数的共享变量,使用volatile关键字声明,目的是第一时间获取修改的内容,性能非常好。
package com.itmayiedu.day03;

import java.util.concurrent.CountDownLatch;

public class CoundDownLatchDemo01 {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(2);//设置初始值为2
        System.out.println("我是主线程。。。。。。");
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("================>>>>>>>>>我是子线程1,开始执行任务");
                try{
                    Thread.sleep(1000);
                    countDownLatch.countDown();//每次减1
                    System.out.println("=================>>>>>>>>>>子线程1,正在执行任务。。。。");
                }catch (Exception ex){

                }
                System.out.println("===================>>>>>>>>子线程1执行任务结束。。");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("=====================>>>>>>>>>我是子线程2,开始执行任务。。");
                try {
                    Thread.sleep(1000);
                    countDownLatch.countDown();//每次减1
                    System.out.println("=============>>>>>>>>>>子线程2,正在执行。。。。");
                }catch (Exception ex){

                }
                System.out.println("================>>>>>>>子线程2执行结束。。。");
            }
        }).start();
       try{
           countDownLatch.await();//如果countDown不为0 的话 就处于一直等待状态,等于0的话就执行下面的代码块
       }catch (Exception ex){

       }
        System.out.println("主线程开始执行任务。。。");
        for (int i = 0; i <10 ; i++) {
            System.out.println("=========>>>>>>"+i+" "+Thread.currentThread().getName());
        }
    }
}

CyclicBarrier也可以当作计数器使用:当线程的数量达到指定的数量是线程并发执行。

package com.itmayiedu.day03;


import java.util.concurrent.CyclicBarrier;

class write extends Thread{
    CyclicBarrier cyclicBarrier;
    public write(CyclicBarrier cyclicBarrier){
        this.cyclicBarrier =cyclicBarrier;
    }
    @Override
    public void run() {
        System.out.println("开始写入数据。。。。。。");
        try{
            Thread.sleep(4000);
        }catch (Exception ex){

        }
        System.out.println(Thread.currentThread().getName()+" "+"数据写入成功");
      try{
          cyclicBarrier.await();//当前线程处于等到状态,所有的线程执行完毕在执行其后的代码。
      }catch (Exception ex){

      }
        //等所有的线程执行完毕后在执行这段代码。
        System.out.println(Thread.currentThread().getName()+" 所有数据执行完毕");
    }
}
public class CyclicBarrierDemo01 {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
        write write = new write(cyclicBarrier);
        Thread t1 = new Thread(write);
        Thread t2 = new Thread(write);
        Thread t3 = new Thread(write);
        Thread t4 = new Thread(write);
        Thread t5 = new Thread(write);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

Semaphore:
是一种基于计数 的信号量,他可以是一个阀值,基于此多个线程竞争获取许可信号,做自己的申请后归还,超过阀值后,线程申请许可信号将会被阻塞,Semaphore可以用来构建一些对象池,资制这也叫二元信号量,标示两种互斥状态,
用法如下:
availablePermits函数用来获取当前可用的资源数量。
wc.acquire():申请资源。
wc.release();释放资源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值