자바에서 BlockingQueue 사용 설명 기반

4398 단어 javablockingqueue
최근에 자바 프로젝트를 유지하고 있는데, 그룹에서도 자바의 우열을 이야기하기 시작합니다!어쩔 수 없이 일부 자바의 궁극적인 팬들은 항상 성능이 이미 C++가 나쁘지 않다고 주장하며 많은 표준 라이브러리들이 대가급 사람들이 쓴 것이다. 어떻게 안정되는지 등이다.차라리 진지하게 한 번 연구해 보자. 그들이 나에게 준 설명 중 하나는 바로 라인 사이에서 메시지를 보내는 것이다. 자바가 이미 봉인된 BlockingQueue를 사용하면 충분하다는 것이다.기왕 충분하면 코드 테스트를 쓰겠습니다. 간단명료하게 작은 프로그램만 써서 테스트를 했습니다.

//
import java.util.concurrent.*;

import base.MyRunnable;

public class Test
{
    public static void main(String[] args)
    {
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>();
        java.lang.Runnable r = new MyRunnable(queue);
        Thread t = new Thread(r);
        t.start();

        while(true)
        {
            try
            {
                while(true)
                {
                    for(int i =0;i < 10000;i++)
                    {
                        queue.offer(i);
                    }
                }
            }
            catch ( Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

 
//
package base;

import java.lang.Runnable;
import java.util.concurrent.*;
import java.util.*;

public class MyRunnable implements Runnable
{
    public MyRunnable(BlockingQueue<Integer> queue)
    {
        this.queue = queue;
    }
    public void run()
    {
        Date d = new Date();
        long starttime = d.getTime();
        System.err.println(starttime);
        int count = 0;
        while(true)
        {
            try
            {
                Integer i = this.queue.poll();
                if(i != null)
                {
                    count ++;
                }
                if(count == 100000)
                {
                    Date e = new Date();
                    long endtime = e.getTime();
                    System.err.println(count);
                    System.err.println(endtime);
                    System.err.print(endtime - starttime);
                    break;
                }

            }
            catch (Exception e)
            {

            }
        }
    }
    private BlockingQueue<Integer> queue;
}
10만 개의 데이터를 전달하는데 제 테스트기 위에 50ms 정도가 필요합니다. 그래도 괜찮습니다!차라리 BlockingQueue의 밑바닥 실현을 봤습니다. 제가 위의 테스트 코드에서 사용한 offer와poll을 보았습니다. 이 두 가지 실현 함수를 보십시오. 우선 offer

public E poll() {
        final AtomicInteger count = this.count;
        if (count.get() == 0)
            return null;
        E x = null;
        int c = -1;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lock();
        try {
            if (count.get() > 0) {
                x = extract();
                c = count.getAndDecrement();
                if (c > 1)
                    notEmpty.signal();
            }
        } finally {
            takeLock.unlock();
        }
        if (c == capacity)
            signalNotFull();
        return x;
    }
는 일반적인 동기화 루트와 유사합니다. 단지 하나의 시그널을 추가했습니다. 유닉스 환경의 고급 프로그래밍을 배울 때 조건 변수가 루트 간의 동기화에 사용되는 것을 보면 루트가 경쟁적인 방식으로 동기화를 실현할 수 있습니다!poll 함수의 실현도 유사합니다!

public boolean offer(E e) {
        if (e == null) throw new NullPointerException();
        final AtomicInteger count = this.count;
        if (count.get() == capacity)
            return false;
        int c = -1;
        final ReentrantLock putLock = this.putLock;
        putLock.lock();
        try {
            if (count.get() < capacity) {
                insert(e);
                c = count.getAndIncrement();
                if (c + 1 < capacity)
                    notFull.signal();
            }
        } finally {
            putLock.unlock();
        }
        if (c == 0)
            signalNotEmpty();
        return c >= 0;
    }

좋은 웹페이지 즐겨찾기