java多线程基本概述(九)——Lock(2)

公平锁与非公平锁:公平锁代表获取锁的顺序时按照加入锁的顺序来分配的,即按照FIFO(first in first out)的顺序来的,而非公平锁就时一种抢占式,是随机分配的。不一定先到先地。这就有可能导致某些线程一致获取不到锁。

package soarhu;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
  private Lock lock ;

    public TestNum(boolean fair) {
        lock = new ReentrantLock(fair);

    }

    public void test(){
          lock.lock();
      try {
          System.out.println(Thread.currentThread().getName()+"  lock ");
      } finally {
          lock.unlock();
      }
  }

}
public class Test{
    public static void main(String[] args)  {
        TestNum t = new TestNum(true);
        for (int i = 0; i < 5; i++) {
            new Thread(){
                @Override
                public void run() {
                    t.test();
                    System.out.println(Thread.currentThread().getName()+" get lock ");
                }
            }.start();
        }
    }
}

输出结果:

Thread-0  lock
Thread-1  lock
Thread-0 get lock
Thread-1 get lock
Thread-3  lock
Thread-3 get lock
Thread-2  lock
Thread-2 get lock
Thread-4  lock
Thread-4 get lock 

Process finished with exit code 0

如果改为:

public class Test{
    public static void main(String[] args)  {
        TestNum t = new TestNum(false);
        for (int i = 0; i < 5; i++) {
            new Thread(){
                @Override
                public void run() {
                    t.test();
                    System.out.println(Thread.currentThread().getName()+" get lock ");
                }
            }.start();
        }
    }
}

输出结果:

Thread-0  lock
Thread-2  lock
Thread-2 get lock
Thread-0 get lock
Thread-1  lock
Thread-1 get lock
Thread-4  lock
Thread-4 get lock
Thread-3  lock
Thread-3 get lock 

Process finished with exit code 0

可见不是按照FIFO来进行分配地。

getHoldCount()、getQueueLength()、getWaitQueLength()、hasQueuedThread()、hasQueuedThreads()、hasWatiers().

1>getHoldCount()表示查询当前线程保持此锁定的个数,也就是调用lock()方法的次数。

package soarhu;

import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    private ReentrantLock lock ;

    public TestNum(boolean fair) {
        lock = new ReentrantLock(fair);

    }

    public void test(){
        System.out.println("enter test getHoldCount="+lock.getHoldCount());
          lock.lock();
      try {
          System.out.println("try test getHoldCount="+lock.getHoldCount());
          test2();
      } finally {
          System.out.println("test before finish getHoldCount="+lock.getHoldCount());
          lock.unlock();
          System.out.println("test after finish getHoldCount="+lock.getHoldCount());
      }
    }

    public void test2(){
        System.out.println("enter test2 getHoldCount="+lock.getHoldCount());
        lock.lock();
        try {
            System.out.println("try test2 getHoldCount="+lock.getHoldCount());
        } finally {
            System.out.println("test2 before finish getHoldCount="+lock.getHoldCount());
            lock.unlock();
            System.out.println("test2 after finish getHoldCount="+lock.getHoldCount());
        }
    }

}
public class Test{
    public static void main(String[] args)  {
        TestNum t = new TestNum(false);
        t.test();
    }
}

输出结果:

enter test getHoldCount=0
try test getHoldCount=1
enter test2 getHoldCount=1
try test2 getHoldCount=2
test2 before finish getHoldCount=2
test2 after finish getHoldCount=1
test before finish getHoldCount=1
test after finish getHoldCount=0

Process finished with exit code 0

2>getQueueLength()表示查询等待获取此锁定的大概个数。api:

public final int getQueueLength()
Returns an estimate of the number of threads waiting to acquire this lock. The value is only an estimate because the number of threads may change dynamically while this method traverses internal data structures. This method is designed for use in monitoring of the system state, not for synchronization control.
------------------------------------------------------------------------------
返回等待获取的线程数的估计数。该值只是一个估计,因为线程数可能会在此方法遍历内部数据结构时动态更改。该方法设计用于监控系统状态,不用于同步控制。

例子:

package soarhu;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    public final ReentrantLock lock ;

    public TestNum(boolean fair) {
        lock = new ReentrantLock(fair);

    }

    public void test(){
          lock.lock();
      try {
          System.out.println(Thread.currentThread().getName()+"Enter");
          //Thread.sleep(Integer.MAX_VALUE);
          lock.lock();
      } catch (Exception e) {
          e.printStackTrace();
      } finally {
          lock.unlock();
      }
    }

}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum(false);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(runnable);
        }
        for (int i = 0; i < 10; i++) {
            threads[i].start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println("holdCont="+t.lock.getHoldCount()+"  queueLength="+t.lock.getQueueLength());
        threads[2].stop();
        TimeUnit.SECONDS.sleep(8);
        System.out.println("holdCont="+t.lock.getHoldCount()+"  queueLength="+t.lock.getQueueLength());
    }
}

输出结果:

Thread-0Enter
holdCont=0  queueLength=9
holdCont=0  queueLength=8

Process finished with exit code 1

3>getQueueLength(Conditon condition)表示返回等待与此锁定相关给定条件的Condition的线程估计数。api:

Returns an estimate of the number of threads waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, the estimate serves only as an upper bound on the actual number of waiters. This method is designed for use in monitoring of the system state, not for synchronization control.
----------------------------------------------
返回与此锁相关联的给定条件等待的线程数的估计。 请注意,由于超时和中断可能在任何时间发生,估计仅作为实际服务员人数的上限。 该方法设计用于监视系统状态,不用于同步控制。
package soarhu;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
     final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();

     TestNum(boolean fair) {
        super();
    }

     void test() {
          lock.lock();
      try {
          condition.await();
      } catch (Exception e) {
          e.printStackTrace();
      } finally {
          lock.unlock();
      }
    }

    void test2() throws InterruptedException {
        lock.lock();

        try {
            System.out.println("count="+lock.getWaitQueueLength(condition));
            condition.signal();
            System.out.println("count="+lock.getWaitQueueLength(condition));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum(false);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(runnable);
        }
        for (int i = 0; i < 10; i++) {
            threads[i].start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println("holdCont="+t.lock.getHoldCount()+"  queueLength="+t.lock.getQueueLength());
        t.test2();
    }
}

输出结果:

holdCont=0  queueLength=0
count=10
count=9

4>hasQueuedThread(Thread thread)表示查询指定的线程是否正在等待获取此锁定。api:

public final boolean hasQueuedThread(Thread thread)
Queries whether the given thread is waiting to acquire this lock. Note that because cancellations may occur at any time, a true return does not guarantee that this thread will ever acquire this lock. This method is designed primarily for use in monitoring of the system state.
---------------------------------------------------------------
查询给定线程是否等待获取此锁。 请注意,由于取消可能会在任何时候发生,真正的返回并不能保证此线程将获得此锁。 该方法主要用于监视系统状态。

例子:

package soarhu;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    public final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();

     TestNum(boolean fair) {
        super();
    }

     void test() {
          lock.lock();
      try {
          Thread.sleep(Integer.MAX_VALUE);
      } catch (Exception e) {
          e.printStackTrace();
      } finally {
          lock.unlock();
      }
    }

    void test2() throws InterruptedException {
        lock.lock();

        try {
            System.out.println("count="+lock.getWaitQueueLength(condition));
            condition.signal();
            System.out.println("count="+lock.getWaitQueueLength(condition));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum(false);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        t1.start();
        Thread.sleep(500);
        t2.start();
        System.out.println("t1   "+t.lock.hasQueuedThread(t1));
        System.out.println("t2   "+t.lock.hasQueuedThread(t2));
        System.out.println("is?  "+t.lock.hasQueuedThreads());
    }
}

输出结果:

t1   false
t2   true
is?  true

Process finished with exit code 1

5>hasWaiters(Condition condition)表示查询是否有线程正在等待此锁定有关的Condition。api:

Queries whether any threads are waiting on the given condition associated with this lock. Note that because timeouts and interrupts may occur at any time, a true return does not guarantee that a future signal will awaken any threads. This method is designed primarily for use in monitoring of the system state.
--------------------------------------------------------------------
查询任何线程是否等待与此锁相关联的给定条件。 请注意,由于超时和中断可能在任何时候发生,真正的返回并不能保证未来的信号将唤醒任何线程。 该方法主要用于监视系统状态。
package soarhu;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

class TestNum {
    final ReentrantLock lock = new ReentrantLock(true);
    private Condition condition = lock.newCondition();

    TestNum(boolean fair) {
        super();
    }

    void test() {
        lock.lock();
        try {
            condition.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    void test2() throws InterruptedException {
        lock.lock();

        try {
            System.out.println("waitQueueLength count="+lock.getWaitQueueLength(condition)+
                                "  hasWaiters?"+lock.hasWaiters(condition));
            condition.signal();
            System.out.println("waitQueueLength count="+lock.getWaitQueueLength(condition)+
                                "  hasWaiters?"+lock.hasWaiters(condition));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

}
public class Test{
    public static void main(String[] args) throws InterruptedException {
        TestNum t = new TestNum(false);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                t.test();
            }
        };
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(runnable);
        }
        for (int i = 0; i < 10; i++) {
            threads[i].start();
        }
        TimeUnit.SECONDS.sleep(2);
        System.out.println("holdCont="+t.lock.getHoldCount()+"  queueLength="+t.lock.getQueueLength());
        t.test2();
    }
}

输出结果:

holdCont=0  queueLength=0
waitQueueLength count=10  hasWaiters?true
waitQueueLength count=9  hasWaiters?true

Process finished with exit code 1
时间: 2024-10-04 06:30:23

java多线程基本概述(九)——Lock(2)的相关文章

Java多线程编程中的lock使用源码详解

将做工程过程重要的代码段做个记录,如下的代码内容是关于Java多线程编程中的lock使用详解的代码,应该是对码农有帮助. import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.locks.Lock; import java.util.concurrent.l

“全栈2019”Java多线程第十九章:死锁详解

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多线程第十九章:死锁详解 下一章 "全栈2019"Java多线程第二十章:同步方法产生死锁的例子 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组&q

java多线程基本概述(九)——ThreadLocal

public interface Lock Lock implementations provide more extensive locking operations than can be obtained using synchronized methods and statements. //Lock对象提供比同步方法或者同步块更多的灵活性和拓展性,They allow more flexible structuring, may have quite different propert

Java多线程——&lt;一&gt;概述、定义任务

一.概述 为什么使用线程?从c开始,任何一门高级语言的默认执行顺序是“按照编写的代码的顺序执行”,日常开发过程中写的业务逻辑,但凡不涉及并发的,都是让一个任务顺序执行以确保得到想要的结果.但是,当你的任务需要处理的业务比较多时,且这些业务前后之间没有依赖(比如, a执行的过程中b也可以执行,b没有必要必须等待a执行完毕再去执行),那么此时,我们可以将一个任务拆分成多个小任务. 例如,任务a负责接收键盘的输入,b负责将一些参数及计算提前做好(假设计算量比较大),c负责将a的输入和b的结果做和.此时

java多线程基本概述

1.1.概念: 进程:进程是操作系统结构的基础,是一次程序的执行:是一个程序及其数据再处理器上顺序执行时所发生的活动:是程序再一个数据集合上运行的过程,它是系统进行系统资源分配和调度的最小单元. 线程:可以理解为一个程序的不同执行路径,是程序执行流的最小单元.线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源.一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发

java多线程基本概述(六)——简单生产者消费者模式

在线程里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据.同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者.为了解决这个问题于是引入了生产者和消费者模式.下面实现一个简单的生产者消费者模式: 1.一个消费者一个生产者循环消费生产 package soarhu; import java.util.ArrayList; import java.util.Lis

java多线程知识点概述

这里只起一个概述的作用,极其简单的列一下知识点,需要在脑海中过一下,如果哪些方面不熟悉的话,建议利用网络资源去学习. 1.线程.进程概念 概念 线程状态及其转换 2.死锁.预防.解决 3.jdk线程实现方式 继承Thread重写run方法.实现Runnable实现run方法.实现Callable重写call方法 call方法能抛出异常允许有返回值 join/jield/interrupt/stop/wait/sleep/setDaemon/suspend 4.线程同步.线程异步 同步使用场景:共

java多线程基本概述(四)——死锁

package mytask; public class Task { public static void main(String[] args) { DeadThread thread = new DeadThread(); Thread t1 = new Thread(thread); t1.setName("a"); Thread t2 = new Thread(thread); t2.setName("b"); t1.start(); t2.start()

java多线程基本概述(五)——线程通信

线程之间的通信可以通过共享内存变量的方式进行相互通信,也可以使用api提供的wait(),notify()实现线程之间的通信.wait()方法是Object类的方法,改方法用来将当前的线程置入"预执行队列"中,并且在wait()方法代码处停止执行进行等待,知道接收到同一个monitor对象的notify()或者notifyAll()方法的通知或者是收到中断.在调用wait()方法之前,线程必须获得锁,即只能在同步方法或者同步块中调用wait()方法,在执行wait()后,当前线程释放锁