gpt4 book ai didi

java - 与信号量同步线程

转载 作者:行者123 更新时间:2023-12-01 04:13:25 29 4
gpt4 key购买 nike

我正在尝试使用信号量同步一些线程。目标是按顺序重复打印 1(8 次)、2(4 次)、4(2 次)和 8(1 次)的序列。我的程序在完成大约 90% 之前都可以正常工作,然后在 2 和 4 上就出错了。我一生都无法弄清楚是什么导致了这个问题。有什么建议么?

public class ThreadSync
{

private static int count = 100;

private static Semaphore printSomeOnes = new Semaphore(1);
private static Semaphore printSomeTwos = new Semaphore(0);
private static Semaphore printSomeFours = new Semaphore(0);
private static Semaphore printSomeEights = new Semaphore(0);


private static boolean runFlag = true;

public static void main( String[] args ) {

// create and start each runnable
Runnable task1 = new TaskPrint1();
Runnable task2 = new TaskPrint2();
Runnable task3 = new TaskPrint4();
Runnable task4 = new TaskPrint8();

Thread thread1 = new Thread( task1 );
Thread thread2 = new Thread( task2 );
Thread thread3 = new Thread( task3 );
Thread thread4 = new Thread( task4 );

thread1.start();
thread2.start();
thread3.start();
thread4.start();



// Let them run for 500ms
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}


// put up the stop sign
runFlag=false;

thread4.interrupt();
thread3.interrupt();
thread2.interrupt();
thread1.interrupt();

}

public static class TaskPrint1 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 8 == 0){
try {
printSomeOnes.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "1");
if(i % 8 == 0){
printSomeTwos.release();
}
}
}
}
}

public static class TaskPrint2 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 4 == 0){
try {
printSomeTwos.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "2");
if(i % 4 == 0){
printSomeFours.release();
}
}
}
}
}

public static class TaskPrint4 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
if(i % 2 == 0){
try {
printSomeFours.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.printf( "%s\n", "4");
if(i % 2 == 0){
printSomeEights.release();
}
}
}
}
}

public static class TaskPrint8 implements Runnable
{
public void run(){
while (runFlag) {
for(int i = 0; i < count; i++){
try {
printSomeEights.acquire();
}
catch (InterruptedException ex) {
ex.printStackTrace();
}
System.out.printf( "%s\n", "8");
printSomeOnes.release();
}
}
}
}

}

最佳答案

我所做的一些更改:

使用Thread.currentThread().isInterrupted()删除runFlag,这是处理这种情况的最佳方法。当发生 InterruptedException 时,只需重置线程的中断标志,以便更高级别的代码对其执行操作。如:

                     try {
printSomeOnes.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}

这里,当发生 InterruptedException 时,只需重置标志,以便
while (!Thread.currentThread().isInterrupted()) { 可以采取相应的行动。这就是我们应该采取的方式来处理这个问题。希望对您有所帮助。

public class ThreadSync {

private static int count = 100;
private static Semaphore printSomeOnes = new Semaphore(1);
private static Semaphore printSomeTwos = new Semaphore(0);
private static Semaphore printSomeFours = new Semaphore(0);
private static Semaphore printSomeEights = new Semaphore(0);
private static volatile boolean runFlag = true;

public static void main(String[] args) {

// create and start each runnable
Runnable task1 = new TaskPrint1();
Runnable task2 = new TaskPrint2();
Runnable task3 = new TaskPrint4();
Runnable task4 = new TaskPrint8();

Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
Thread thread4 = new Thread(task4);

thread1.start();
thread2.start();
thread3.start();
thread4.start();



// Let them run for 500ms
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}


// put up the stop sign
// runFlag=false;

thread4.interrupt();
thread3.interrupt();
thread2.interrupt();
thread1.interrupt();

}

public static class TaskPrint1 implements Runnable {

@Override
public void run() {

while (!Thread.currentThread().isInterrupted()) {

for (int i = 0; i < count; i++) {
if (i % 8 == 0) {
try {
printSomeOnes.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
System.out.printf("%s\n", "1");
if (i % 8 == 0) {
printSomeTwos.release();
}
}
}

}
}

public static class TaskPrint2 implements Runnable {

@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 0; i < count; i++) {
if (i % 4 == 0) {
try {
printSomeTwos.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
System.out.printf("%s\n", "2");
if (i % 4 == 0) {
printSomeFours.release();
}
}
}
}
}

public static class TaskPrint4 implements Runnable {

@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 0; i < count; i++) {
if (i % 2 == 0) {
try {
printSomeFours.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
}
System.out.printf("%s\n", "4");
if (i % 2 == 0) {
printSomeEights.release();
}
}
}
}
}

public static class TaskPrint8 implements Runnable {

@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
for (int i = 0; i < count; i++) {
try {
printSomeEights.acquire();
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
break;
}
System.out.printf("%s\n", "8");
printSomeOnes.release();
}
}
}
}
}

关于java - 与信号量同步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19673111/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com