获取synchronized锁中的阻塞队列中的线程是非公平的

synchronized中阻塞队列的线程是非公平的

测试demo:

import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class SleepState {

    public static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        }
    };

    private static final int[] lock = new int[0];

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new TestSynchronizedTask(lock, 1000 * 10), "Thread1");
        Thread thread2 = new Thread(new TestSynchronizedTask(lock, 10), "Thread2");
        Thread thread3 = new Thread(new TestSynchronizedTask(lock, 1000), "Thread3");
        thread1.start();
        TimeUnit.MILLISECONDS.sleep(1000);
        thread2.start();
        TimeUnit.MILLISECONDS.sleep(1000);
        thread3.start();
    }
}

class TestSynchronizedTask implements Runnable {
    private final int[] lock;
    private int sleepMilliSeconds;

    public TestSynchronizedTask(int[] lock, int sleepMilliSeconds) {
        this.lock = lock;
        this.sleepMilliSeconds = sleepMilliSeconds;
    }

    public TestSynchronizedTask(int[] lock) {
        this(lock, 0);
    }

    @Override
    public void run() {
        synchronized (lock) {
            try {
                System.out.println(MessageFormat.format(" {0} {1}  begin", SleepState.threadLocal.get().format(new Date()), Thread.currentThread()));
                TimeUnit.MILLISECONDS.sleep(sleepMilliSeconds);
                System.out.println(MessageFormat.format("{0} {1}  will end", SleepState.threadLocal.get().format(new Date()), Thread.currentThread()));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
执行结果:
 2016-05-26 13:31:44.260+0800 Thread[Thread1,5,main]  begin
2016-05-26 13:31:54.260+0800 Thread[Thread1,5,main]  will end
 2016-05-26 13:31:54.260+0800 Thread[Thread3,5,main]  begin
2016-05-26 13:31:55.260+0800 Thread[Thread3,5,main]  will end
 2016-05-26 13:31:55.260+0800 Thread[Thread2,5,main]  begin
2016-05-26 13:31:55.276+0800 Thread[Thread2,5,main]  will end
时间: 2024-08-01 11:39:34

获取synchronized锁中的阻塞队列中的线程是非公平的的相关文章

Java中的阻塞队列

1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用.阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程.阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素. 阻塞队列提供了四种处理方法: 方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put

聊聊并发(七)——Java中的阻塞队列

1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用.阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程.阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素. 阻塞队列提供了四种处理方法: 方法\处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put

聊聊并发(七)Java中的阻塞队列

什么是阻塞队列 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用.阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程.阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素. 阻塞队列提供了四种处理方法: 抛出异常:是指当阻塞队列满时候,再往队列里插入元素,会抛出IllegalStateException("Queue

Java中的阻塞队列(二)

原文地址:http://benjaminwhx.com/2018/05/11/%E3%80%90%E7%BB%86%E8%B0%88Java%E5%B9%B6%E5%8F%91%E3%80%91%E8%B0%88%E8%B0%88LinkedBlockingQueue/ 在集合框架里,想必大家都用过ArrayList和LinkedList,也经常在面试中问到他们之间的区别.ArrayList和ArrayBlockingQueue一样,内部基于数组来存放元素,而LinkedBlockingQueu

多线程编程学习六(Java 中的阻塞队列).

介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取元素的容器. 当线程 插入/获取 动作由于队列 满/空 阻塞后,队列也提供了一些机制去处理,或抛出异常,或返回特殊值,或者线程一直等待... 方法/处理方式 抛出异常 返回特殊值 一直阻塞 超时退出 插入方法 add(e) offer(e) put(e) offer(e, timeout, unit

并发编程中的阻塞队列概述

1.简介 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作支持阻塞的插入和移除方法. 1)支持阻塞的插入方法:意思是当队列满时,队列会阻塞插入元素的线程,直到队列不满. 2)支持阻塞的移除方法:意思是在队列为空时,获取元素的线程会等待队列变为非空. 阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素的线程,消费者是从队列里取元素的线程.阻塞队列就是生产者用来存放元素.消费者用来获取元素的容器. 在阻塞队列不可用时,插入.移除这两个附加操作提供4种处理

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法. 这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性. 2.如何实现? 主要是实现Blo

synchronized关键字,Lock对象,阻塞队列问题

一.   请你谈一谈synchronized和lock有什么区别? 1.synchronized是java的关键字,属于jvm层面,底层是通过moninter对象实现的.Lock是具体的接口,属于api层面. 2.synchronized不需要用户去手动释放锁,当synchronized的代码执行完成后,系统会自动释放线程对锁的占用,Lock 则需要用户去手动释放锁,如果没有主动去释放锁,就会导致死锁的发生. 3.synchronized不可被中断,除非程序执行完毕或抛出异常.Lock可以被中断

阻塞队列模型和线程池

阻塞队列模型介绍 阻塞队列模型和线程池息息相关,因此本篇博客先介绍阻塞队列的相关知识.如下图所示: 首先我们来说,什么是Queue,然后在谈什么是BlockingQueue. 那么什么是Queue呢?一句话,就是一端进,另一端出,这样就形成了First In , First Out,即先进先出.而BlockingQueue只不过是在Queue的基础上进行了2个附加操作而已:如果Queue空,那么Out线程阻塞,如果Queue满,那么In线程阻塞. 理解了上面的Queue/BlockingQueu