Java多线程程序NotifyListener行为



我一直在编写一个简单的程序,试图了解Java的多线程功能与监听器的结合,以便在线程关闭时用作通知代理。以下是正在使用的接口/类(主要是从网络上获取并进行了一些调整(:

public interface ThreadCompleteListener {
void notifyOfThreadComplete(final NotifyingThread thread);
}
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}
@Override
public final void run() {
try {
doRun();
} finally {
notifyListeners();
}
}


public abstract void doRun();
}

类调用线程的版本1

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class InvokeThread implements ThreadCompleteListener{
List<String> synList = Collections.synchronizedList(new ArrayList<String>());
int threadNotifyCount = 0;
String threadList = "";

public static void main(String[] args) {        
InvokeThread ma_0 = new InvokeThread();     
ma_0.execute(args);
}
@Override
public void notifyOfThreadComplete(NotifyingThread thread) {
String _temp = threadList.substring(0, threadList.length()-1);
threadNotifyCount++;
if(threadNotifyCount == _temp.split(",").length) {
Collections.sort(synList);
System.out.println(thread.getName() + ": " + synList);
}               
}

public String execute(String[] args) {

// Start the Thread
NotifyingThread thread1 = new NotifyingThread() {

@Override
public void doRun() {
synchronized (this) {
//                  synList.addAll(Arrays.asList("zebra", "cow", "rabbit"));
threadList = this.getName() + "," + threadList;
synList.addAll(Arrays.asList(args[0].split(",")));
}

}
};

thread1.addListener(this); 
thread1.start();

NotifyingThread thread2 = new NotifyingThread() {

@Override
public void doRun() {               
synchronized (this) {
threadList = this.getName() + "," + threadList;
synList.addAll(Arrays.asList(args[idx].split(",")));
}                               
}
};

thread2.addListener(this);
thread2.start();

return "";
}
}

类调用线程的版本2

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class InvokeThread implements ThreadCompleteListener{
List<String> synList = Collections.synchronizedList(new ArrayList<String>());
int threadNotifyCount = 0;
String threadList = "";

public static void main(String[] args) {        
InvokeThread ma_0 = new InvokeThread();     
ma_0.execute(args);
}
@Override
public void notifyOfThreadComplete(NotifyingThread thread) {
String _temp = threadList.substring(0, threadList.length()-1);
threadNotifyCount++;
if(threadNotifyCount == _temp.split(",").length) {
Collections.sort(synList);
System.out.println(thread.getName() + ": " + synList);
}               
}

public String execute(String[] args) {

int argsCount = args.length;

for(int idx=0;idx<argsCount;idx++) {
NotifyingThread thread = new NotifyingThread() {

@Override
public void doRun() {               
synchronized (this) {
threadList = this.getName() + "," + threadList;
synList.addAll(Arrays.asList(args[1].split(",")));
}                               
}
};
thread.addListener(this);
thread.start();
}   

return "";
}
}

输入参数:

"zebra,cow,rabbit"
"giraffe,camel,buffalo"

上面给出了给定类InvokeThread的两个版本。第一个版本确实一致地打印了String对象的排序列表。第二个版本偶尔不打印任何内容。请帮我理解这件事。TIA。

EDIT-1(在更改代码以修复Solomon在评论部分报告的错误之后(:

NotifyingThread:版本2

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}

private int idx;
public NotifyingThread(int index) {
this.idx = index;
}
@Override
public final void run() {
try {
doRun(idx);
} finally {
notifyListeners();
}
}


public abstract void doRun(int idx);
}

InvokeThread:的2.1版

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class InvokeThread implements ThreadCompleteListener{
List<String> synList = Collections.synchronizedList(new ArrayList<String>());
int threadNotifyCount = 0;
String threadList = "";

public static void main(String[] args) {        
InvokeThread ma_0 = new InvokeThread();     
ma_0.execute(args);
}
@Override
public void notifyOfThreadComplete(NotifyingThread thread) {
String _temp = threadList.substring(0, threadList.length()-1);
threadNotifyCount++;
if(threadNotifyCount == _temp.split(",").length) {
Collections.sort(synList);
System.out.println(thread.getName() + ": " + synList);
}               
}

public String execute(String[] args) {

int argsCount = args.length;

for(int idx=0;idx<argsCount;idx++) {
NotifyingThread thread = new NotifyingThread(idx) {

@Override
public void doRun(int idx) {                
synchronized (this) {
//                      synList.addAll(Arrays.asList("giraffe", "camel", "buffalo"));
threadList = this.getName() + "," + threadList;
synList.addAll(Arrays.asList(args[idx].split(",")));
}                               
}
};
thread.addListener(this);
thread.start();
}           

return "";
}
}

fixture确实修复了最初报告的问题,即此类的v2偶尔不打印列表。然而,我想保留这个问题,要求澄清所罗门关于不同步的言论。

以下更改(由于Solomon的提示(提供了固定装置:

NotifyingThread:版本2

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public abstract class NotifyingThread extends Thread {
private final Set<ThreadCompleteListener> listeners = new CopyOnWriteArraySet<ThreadCompleteListener>();
public final void addListener(final ThreadCompleteListener listener) {
listeners.add(listener);
}
public final void removeListener(final ThreadCompleteListener listener) {
listeners.remove(listener);
}
private final void notifyListeners() {
for (ThreadCompleteListener listener : listeners) {
listener.notifyOfThreadComplete(this);
}
}

private int idx;
public NotifyingThread(int index) {
this.idx = index;
}
@Override
public final void run() {
try {
doRun(idx);
} finally {
notifyListeners();
}
}


public abstract void doRun(int idx);
}

InvokeThread:的2.1版

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class InvokeThread implements ThreadCompleteListener{
List<String> synList = Collections.synchronizedList(new ArrayList<String>());
int threadNotifyCount = 0;
String threadList = "";

public static void main(String[] args) {        
InvokeThread ma_0 = new InvokeThread();     
ma_0.execute(args);
}
@Override
public void notifyOfThreadComplete(NotifyingThread thread) {
String _temp = threadList.substring(0, threadList.length()-1);
threadNotifyCount++;
if(threadNotifyCount == _temp.split(",").length) {
Collections.sort(synList);
System.out.println(thread.getName() + ": " + synList);
}               
}

public String execute(String[] args) {

int argsCount = args.length;

for(int idx=0;idx<argsCount;idx++) {
NotifyingThread thread = new NotifyingThread(idx) {

@Override
public void doRun(int idx) {                
synchronized (this) {
//                      synList.addAll(Arrays.asList("giraffe", "camel", "buffalo"));
threadList = this.getName() + "," + threadList;
synList.addAll(Arrays.asList(args[idx].split(",")));
}                               
}
};
thread.addListener(this);
thread.start();
}           

return "";
}
}

最新更新