Latch的使用详解

Latch的使用详解

     Latch是Oracle为了保护内存结构而发明的一种资源。常应用于并发的用户从磁盘中读取或写入数据。最常见的latch争用有:共享池中latch的争用和数据缓冲池中latch的争用。

1、共享池中latch的争用:

共享池中如果存在大量的SQL语句被反复分析,就很可能造成latch争用和长时间等待,常见的现象是由于没有绑定变量造成的。

SQL> select * from v$latchname where name like 'library cache%'

在分析系统性能时,如果有library cache这样的latch争用,基本可以断定是共享池中出现的问题,这种问题是由SQL语句导致的,比如没有绑定变量或者一些存储过程被反复分析。

 

2、数据缓冲池中latch的争用:
当很多用户一起去访问某几个数据块时,就会导致数据缓冲池的latch争用,主要有两种:buffer busy  waits 和 cache buffer chain。访问频率高的数据块被称为热块(hot block),当很多用户同时访问相同的数据块就会导致热块问题,造成热块的原因可能是数据库设置导致或者重复执行的SQL频繁的访问一些相同的数据块导致的。

2.1查询当前数据库最繁忙的Buffer:TCHTouch)表示访问次数越高,热点块竞争问题就存在
  select *
  from select addr,
  ts#,
  file#,
  dbarfil,
  dbablk,
  tch
  from x$bh
  order by tch desc
  where rownum<11;
2.2结合dba_extents查询得到这些热点Buffer来自哪些对象
  select e.owner, e.segment_name, e.segment_type
  from dba_extents e,
  (select *
  from select addr, ts#, file#, dbarfil, dbablk, tch
  from x$bh
  order by tch desc
  where rownum<11 b
  where e.relative_fno=b.dbarfil
  and e.block_id<=b.dbablk
  and e.block_id+e.blocks>b.dbablk;
2.3结合SQL视图可以找到操作这些对象的相关SQL,然后通过优化SQL减少数据的访问,或者优化某些容易引起争用的操作(如connect by等操作)来减少热点块竞争
  break on hash_value skip 1
  select /*+ rule */ hash_value,sql_text
  from v$sqltext
  where hash_value, address in
  select a.hash_value, a.address
  from v$sqltext a,
  (select distinct a.owner, a.segment_name, a.segment_type
  from dba_extents a,
  (select dbarfil, dbablk
  from select  dbarfil, dbablk
  from x$bh
  order by tch desc
  where rownum<11 b
  where a.relative_fno = b.dbarfil
  and a.block_id <= b.dbablk
  and a.block_id + a.blocks > b.dbablk b
  where a.sql_text like ‘%’ || b.segment_name || ‘%’
  and b.segment_type = ‘TABLE’
  order by  hash_value, address, piece;

 

 

 

CountDownLatch是Java中的一个同步工具类,用于控制多个线程的执行顺序。它通过一个计数器来实现,该计数器初始化为一个正整数,每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器的值减到0时,所有等待的线程就会被唤醒继续执行。 在Android中,CountDownLatch可以用于等待多个异步操作完成后再执行某个任务,或者等待多个线程都达到某个状态后再继续执行。 下面是CountDownLatch的基本使用方法: 1. 创建CountDownLatch对象,并指定计数器的初始值。 ```java CountDownLatch latch = new CountDownLatch(3); // 计数器初始值为3 ``` 2. 在需要等待的地方调用`await()`方法,使当前线程进入等待状态,直到计数器值为0时才会继续执行。 ```java try { latch.await(); // 等待计数器值为0 } catch (InterruptedException e) { e.printStackTrace(); } ``` 3. 在需要通知其他线程继续执行的地方调用`countDown()`方法,将计数器的值减1。 ```java latch.countDown(); // 计数器减1 ``` 下面是一个简单的示例,演示了如何使用CountDownLatch等待多个线程完成后再执行某个任务: ```java import java.util.concurrent.CountDownLatch; public class CountDownLatchExample { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(3); for (int i = 0; i < 3; i++) { final int threadNum = i; new Thread(() -> { try { Thread.sleep(1000); System.out.println("Thread " + threadNum + " completed."); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); } try { latch.await(); System.out.println("All threads completed. Start executing the task..."); // 执行任务 } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在上面的示例中,我们创建了一个初始值为3的CountDownLatch对象。然后创建了3个线程,每个线程会在执行完任务后将计数器减1。主线程调用`await()`方法等待计数器的值变为0,当所有线程都执行完任务后,主线程才会继续执行并输出"All threads completed. Start executing the task..."。 希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值