我正在尝试创建一个使用线程的程序:线程1将整数放入列表中,线程2将偶数过滤到偶数列表中,线程3对奇数执行相同的操作。
public class Manage {
private Object lock = new Object();
private LinkedList<Integer> intStorage = new LinkedList<Integer>();
private LinkedList<Integer> evens = new LinkedList<>();
private LinkedList<Integer> odds = new LinkedList<>();
public void intCollection() throws InterruptedException {
for (int i = 0; i <= 20; i++) {
synchronized(lock) {
while(i == 20) {
lock.wait();
}
intStorage.add(i);
lock.notifyAll();
System.out.println(intStorage);
}
Thread.sleep(100);
}
}
public void evens() throws InterruptedException {
for(int i = 0; i < intStorage.size() ; i++) {
synchronized(lock) {
if(intStorage.get(i) % 2 != 0) {
lock.wait();
}
if(intStorage.get(i) % 2 == 0) {
int j = intStorage.remove(i);
evens.add(j);
lock.notifyAll();
}
System.out.println(evens);
}
Thread.sleep(1000);
}
}
public void odds() throws InterruptedException {
for(int i = 0; i < intStorage.size() ; i++) {
synchronized(lock) {
if(intStorage.get(i) % 2 == 0) {
lock.wait();
}
if(intStorage.get(i) % 2 != 0) {
int j = intStorage.remove(i);
odds.add(j);
lock.notifyAll();
}
System.out.println(odds);
}
Thread.sleep(1000);
}
}
public static void main(String[] args) throws InterruptedException {
Manager m = new Manager();
Thread t1 = new Thread(){
public void run() {
try {
m.intCollection();
} catch (InterruptedException e) {
}
}
};
Thread t2 = new Thread(){
public void run() {
try {
m.evens();
} catch (InterruptedException e) {
}
}
};
Thread t3 = new Thread(){
public void run() {
try {
m.odds();
} catch (InterruptedException e) {
}
}
};
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
}
线程1运行,但是我不能让线程2和线程3来过滤赔率和偶数。程序在线程1完成后终止。
发布于 2018-04-22 03:43:15
这里的问题是您有三个线程竞争一个锁,但您需要intCollection线程首先赢得锁。如果任何其他线程首先赢得锁,你将得到一个由于这个段的越界异常:
for(int i = 0; i < intStorage.size() ; i++) {
synchronized(lock) {
if(intStorage.get(i) % 2 == 0) {
即使intStorage为空,它也会调用get(0)并产生越界异常。
您也不需要通知和等待调用。我在我的解决方案中删除了这些。我添加了一个检查,看看intStorage是否为空,这就是它的全部内容。
以下是完整的答案:
import java.util.*;
public class Manager {
private Object lock = new Object();
private boolean running = true;
private LinkedList<Integer> intStorage = new LinkedList<Integer>();
private LinkedList<Integer> evens = new LinkedList<>();
private LinkedList<Integer> odds = new LinkedList<>();
public void intCollection() throws InterruptedException {
for (int i = 0; i <= 20; i++) {
synchronized(lock) {
intStorage.add(i);
System.out.println("storage: " + intStorage);
}
Thread.sleep(100);
}
running = false;
}
public void evens() throws InterruptedException {
while( (!intStorage.isEmpty()) || running ) {
synchronized (lock) {
if(!intStorage.isEmpty()) {
if (intStorage.get(0) % 2 == 0) {
int j = intStorage.remove(0);
evens.add(j);
}
System.out.println("evens: " + evens);
}
}
Thread.sleep(1);
}
}
public void odds() throws InterruptedException {
while( (!intStorage.isEmpty()) || running ) {
synchronized (lock) {
if(!intStorage.isEmpty()) {
if (intStorage.get(0) % 2 != 0) {
int j = intStorage.remove(0);
odds.add(j);
}
System.out.println("odds: " + odds);
}
}
Thread.sleep(1);
}
}
public static void main(String[] args) throws InterruptedException {
//must be final to access
final Manager m = new Manager();
Thread t1 = new Thread(){
public void run() {
try {
m.intCollection();
} catch (InterruptedException e) {
}
}
};
Thread t2 = new Thread(){
public void run() {
try {
m.evens();
} catch (InterruptedException e) {
}
}
};
Thread t3 = new Thread(){
public void run() {
try {
m.odds();
} catch (InterruptedException e) {
}
}
};
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
}
}
发布于 2018-04-22 04:10:30
在这里,你的go...this运行得很好:唯一需要注意的是改变线程加入的顺序:)
import java.util.LinkedList;
public class Manager {
private Object lock = new Object();
private LinkedList<Integer> intStorage = new LinkedList<Integer>();
private LinkedList<Integer> evens = new LinkedList<>();
private LinkedList<Integer> odds = new LinkedList<>();
public void intCollection() throws InterruptedException {
for (int i = 0; i < 20; i++) {
synchronized (lock) {
while (i == 20) {
lock.wait();
}
intStorage.add(i);
lock.notifyAll();
System.out.println(intStorage);
}
Thread.sleep(100);
}
}
public void evens() throws InterruptedException {
for (int i = 0; i < intStorage.size(); i++) {
synchronized (lock) {
if (intStorage.get(i) % 2 != 0) {
lock.wait();
}
if (intStorage.get(i) % 2 == 0) {
int j = intStorage.remove(i);
evens.add(j);
lock.notifyAll();
}
System.out.println("even" + evens);
}
Thread.sleep(1000);
}
}
public void odds() throws InterruptedException {
for (int i = 0; i < intStorage.size(); i++) {
synchronized (lock) {
if (intStorage.get(i) % 2 == 0) {
lock.wait();
}
if (intStorage.get(i) % 2 != 0) {
int j = intStorage.remove(i);
odds.add(j);
lock.notifyAll();
}
System.out.println("odd:" + odds);
}
Thread.sleep(1000);
}
}
public static void main(String[] args) throws InterruptedException {
Manager m = new Manager();
Thread t1 = new Thread() {
public void run() {
try {
m.intCollection();
} catch (InterruptedException e) {
}
}
};
Thread t2 = new Thread() {
public void run() {
try {
m.evens();
} catch (InterruptedException e) {
}
}
};
Thread t3 = new Thread() {
public void run() {
try {
m.odds();
} catch (InterruptedException e) {
}
}
};
t1.start();
t1.join();
t2.start();
t2.join();
t3.start();
t3.join();
}
}
https://stackoverflow.com/questions/49959345
复制相似问题