建设b2c商城网站云南省最新疫情情况
1.什么是进程同步,为什么要引入进程同步?
- 进程同步是指多个进程在执行次序上进行协调,使它们按一定的规则共享资源和相互合作。引入进程同步是为了避免并发进程因资源竞争而产生数据不一致、混乱等问题,确保系统的稳定性和正确性。
2.同步机制应该遵循的原则是什么?为什么要遵循这些原则(可以通过举例进行解释)
- 同步机制应遵循空闲让进、忙则等待、有限等待和让权等待原则。空闲让进可提高资源利用率,如空闲文件允许多线程写入;忙则等待防数据混乱,像多线程改数据库;有限等待避“饥饿”,保证进程执行;让权等待免忙等,使系统高效运行。
3.什么是信号量,为什么引入信号量机制?
- 信号量是一个整型变量,用于进程同步。它有两个原子操作:P操作(等待)和V操作(释放)。引入信号量机制是为了有效解决进程同步和互斥问题,通过对信号量的操作来控制进程对临界资源的访问,避免因竞争导致的数据不一致等问题。
4.给出记录型信号量wait()和signal()操作的实现代码
import java.util.LinkedList;
import java.util.Queue;class RecordSemaphore {//信号量private int value;//阻塞队列private Queue<Thread> queue;public RecordSemaphore(int value) {this.value = value;this.queue = new LinkedList<>();}public synchronized void waitOp() {value--;if (value < 0) {try {queue.add(Thread.currentThread());// 线程在 RecordSemaphore 对象的监视器上等待this.wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}public synchronized void signalOp() {value++;if (value <= 0) {queue.poll();// 在 RecordSemaphore 对象的监视器上唤醒等待的线程this.notify();}}public static void main(String[] args) {RecordSemaphore semaphore = new RecordSemaphore(1);// 创建线程 1Thread thread1 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 尝试获取信号量");semaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 已获取信号量,正在执行操作...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 操作完成,释放信号量");semaphore.signalOp();}, "Thread-1");// 创建线程 2Thread thread2 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 尝试获取信号量");semaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 已获取信号量,正在执行操作...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 操作完成,释放信号量");semaphore.signalOp();}, "Thread-2");// 创建线程 3Thread thread3 = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 尝试获取信号量");semaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 已获取信号量,正在执行操作...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 操作完成,释放信号量");semaphore.signalOp();}, "Thread-3");// 启动线程thread1.start();thread2.start();thread3.start();// 等待线程执行完成try {thread1.join();thread2.join();thread3.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("所有线程执行完毕");}
}
运行结果1:
Thread-1 尝试获取信号量
Thread-1 已获取信号量,正在执行操作...
Thread-3 尝试获取信号量
Thread-2 尝试获取信号量
Thread-1 操作完成,释放信号量
Thread-3 已获取信号量,正在执行操作...
Thread-3 操作完成,释放信号量
Thread-2 已获取信号量,正在执行操作...
Thread-2 操作完成,释放信号量
所有线程执行完毕
运行结果2:
Thread-1 尝试获取信号量
Thread-1 已获取信号量,正在执行操作...
Thread-2 尝试获取信号量
Thread-3 尝试获取信号量
Thread-1 操作完成,释放信号量
Thread-2 已获取信号量,正在执行操作...
Thread-2 操作完成,释放信号量
Thread-3 已获取信号量,正在执行操作...
Thread-3 操作完成,释放信号量
运行结果3:
Thread-2 尝试获取信号量
Thread-2 已获取信号量,正在执行操作...
Thread-3 尝试获取信号量
Thread-1 尝试获取信号量
Thread-2 操作完成,释放信号量
Thread-3 已获取信号量,正在执行操作...
Thread-3 操作完成,释放信号量
Thread-1 已获取信号量,正在执行操作...
Thread-1 操作完成,释放信号量
所有线程执行完毕
5.用wait(),signal()操作尝试实现司机和售票员进程的同步(利用信号量实现前驱关系)
import java.util.LinkedList;
import java.util.Queue;class RecordSemaphore {// 信号量private int value;// 阻塞队列private Queue<Thread> queue;public RecordSemaphore(int value) {this.value = value;this.queue = new LinkedList<>();}public synchronized void waitOp() {value--;if (value < 0) {try {queue.add(Thread.currentThread());// 线程在 RecordSemaphore 对象的监视器上等待this.wait();} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}public synchronized void signalOp() {value++;if (value <= 0) {queue.poll();// 在 RecordSemaphore 对象的监视器上唤醒等待的线程this.notify();}}public static void main(String[] args) {// 用于控制售票员线程开始的信号量,初始值为 1 表示可以开始RecordSemaphore conductorSemaphore = new RecordSemaphore(1);// 用于控制司机线程开始的信号量,初始值为 0 表示需要等待RecordSemaphore driverSemaphore = new RecordSemaphore(0);// 创建售票员线程Thread conductor = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 尝试获取信号量");conductorSemaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 已获取信号量,正在执行操作...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 操作完成,释放信号量");conductorSemaphore.signalOp();// 售票员操作完成后,释放司机线程的信号量driverSemaphore.signalOp();}, "售票员");// 创建司机线程Thread driver = new Thread(() -> {System.out.println(Thread.currentThread().getName() + " 等待售票员完成操作...");// 等待售票员线程释放信号量driverSemaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 尝试获取信号量");conductorSemaphore.waitOp();System.out.println(Thread.currentThread().getName() + " 已获取信号量,正在执行操作...");try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " 操作完成,释放信号量");conductorSemaphore.signalOp();}, "司机");// 启动线程conductor.start();driver.start();// 等待线程执行完成try {conductor.join();driver.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("所有线程执行完毕");}
}
测试结果如下:
售票员 尝试获取信号量
司机 等待售票员完成操作...
售票员 已获取信号量,正在执行操作...
售票员 操作完成,释放信号量
司机 尝试获取信号量
司机 已获取信号量,正在执行操作...
司机 操作完成,释放信号量
所有线程执行完毕