当前位置:首页 > 行业动态 > 正文

java信号量原理是什么怎么操作

Java信号量(Semaphore)是一种用于控制多线程并发访问的同步工具类,它的原理是基于计数器的,可以用来限制同时访问特定资源的线程数量,信号量的值表示当前可用的资源数,当资源数为0时,线程需要等待;当资源数大于0时,线程可以继续执行。

在Java中,信号量可以通过java.util.concurrent.Semaphore类来实现,Semaphore类提供了一些方法来操作信号量,如acquire()、release()和tryAcquire()等,下面我们将详细介绍如何使用Java信号量。

1、创建信号量对象

我们需要创建一个Semaphore对象,并指定初始的资源数,我们创建一个初始资源数为3的信号量对象:

import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 创建一个初始资源数为3的信号量对象
    }
}

2、获取资源

当一个线程需要访问某个资源时,它需要先调用acquire()方法来获取资源,如果信号量的值为正数,表示有可用的资源,线程将继续执行;如果信号量的值为0,表示没有可用的资源,线程需要等待。

import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 创建一个初始资源数为3的信号量对象
        // 线程1尝试获取资源
        new Thread(() > {
            try {
                semaphore.acquire(); // 获取资源
                System.out.println("线程1获取到资源");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release(); // 释放资源
            }
        }).start();
    }
}

3、释放资源

当一个线程不再需要访问某个资源时,它需要调用release()方法来释放资源,这将使信号量的值加1,允许其他等待的线程继续执行,注意,释放资源的操作必须在finally代码块中进行,以确保即使在异常情况下也能正确释放资源。

import java.util.concurrent.Semaphore;
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 创建一个初始资源数为3的信号量对象
        // 线程1尝试获取资源
        new Thread(() > {
            try {
                semaphore.acquire(); // 获取资源
                System.out.println("线程1获取到资源");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                semaphore.release(); // 释放资源
            }
        }).start();
    }
}

4、尝试获取资源(非阻塞)

除了使用acquire()方法阻塞等待资源外,我们还可以使用tryAcquire()方法尝试获取资源,如果信号量的值为正数,表示有可用的资源,线程将继续执行;如果信号量的值为0,表示没有可用的资源,线程不会等待,而是直接返回false,这样可以避免线程长时间等待资源的情况。

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3); // 创建一个初始资源数为3的信号量对象
        // 线程1尝试获取资源(非阻塞)
        boolean result = semaphore.tryAcquire(); // 尝试获取资源,非阻塞方式
        if (result) { // 如果成功获取到资源,继续执行
            System.out.println("线程1获取到资源");
        } else { // 如果未能获取到资源,执行其他操作或等待一段时间后重试
            System.out.println("线程1未能获取到资源");
        } finally {
            semaphore.release(); // 释放资源(无论是否成功获取到资源)
        }
    }
}

5、超时等待资源(限时获取)

我们希望线程在等待资源的限定时间内能够获取到资源,这时,我们可以使用tryAcquire()方法结合时间参数来实现,我们让线程在1秒内尝试获取资源:

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.*;
import java.util.*;; import javafx.*; import javafx.application.*; import javafx.scene.*; import javafx.scene,layout.*; import javafx,stage.*; import javafx,embed.*; import javafx,scene,control.*; import javafx,scene,input.*; import javafx,scene,paint.*; import javafx,scene,shape.*; import javafx,scene,text.*; import javafx,stage,filedialog.*; import javafx,stage,modaldialog.*; import javafx,stage,alert.*; import javafx,stage,tab.*; import javafx,stage,title.*; import javafx,scene,image.*; import javafx,scene,web.*; import javax,xml,bind.*; import javax,xml,parsers.*; import javax,xml,transform.*; import javax,xml,transform,dom.*; import javax,xml,transform,stream.*; import javax,xml,xpath.*; import org,w3c,dom.*; import org,w3c,dom,events.*; import org,w3c,dom,ls.*; import org,w3c,dom,ranges.*; import org,w3c,dom,stylesheets.*; import org,w3c,dom,traversal.*; import org,w3c,dom,views.*; import org,xml,sax.*; import org,xml,sax,helpers.*; import org,xmlpull.*; import com,sun,org,apache,xerces.*; import com
0