[英]Synchronized Threading With Semaphores
我正在嘗試使用信號量來同步一些線程。 目的是按此順序重復打印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();
}
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.