首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用3线程Java的多线程

使用3线程Java的多线程
EN

Stack Overflow用户
提问于 2018-04-22 03:11:42
回答 2查看 504关注 0票数 2

我正在尝试创建一个使用线程的程序:线程1将整数放入列表中,线程2将偶数过滤到偶数列表中,线程3对奇数执行相同的操作。

代码语言:javascript
运行
复制
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完成后终止。

EN

回答 2

Stack Overflow用户

发布于 2018-04-22 03:43:15

这里的问题是您有三个线程竞争一个锁,但您需要intCollection线程首先赢得锁。如果任何其他线程首先赢得锁,你将得到一个由于这个段的越界异常:

代码语言:javascript
运行
复制
for(int i = 0; i < intStorage.size() ; i++) {

    synchronized(lock) {

        if(intStorage.get(i) % 2 == 0) {

即使intStorage为空,它也会调用get(0)并产生越界异常。

您也不需要通知和等待调用。我在我的解决方案中删除了这些。我添加了一个检查,看看intStorage是否为空,这就是它的全部内容。

以下是完整的答案:

代码语言:javascript
运行
复制
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();

    }
}
票数 1
EN

Stack Overflow用户

发布于 2018-04-22 04:10:30

在这里,你的go...this运行得很好:唯一需要注意的是改变线程加入的顺序:)

代码语言:javascript
运行
复制
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();
}

}

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49959345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档