0

我正在尝试通过实现代码片段来学习多线程。问题是使用 4 个线程(每个 13 个)在四个列表中分配卡片(52),请在下面的代码中提出更好的解决方案或更正。

由于这是为了练习多线程,我没有对命名约定和泛型做太多强调(为此道歉)

import java.util.LinkedList;
import java.util.List;

public class CardsDivideIntoFour {
    static final int Max = 52;
    static int val = 0;
    static Object ox = new Object();
    static List list1 = new LinkedList();
    static List list2 = new LinkedList();
    static List list3 = new LinkedList();
    static List list4 = new LinkedList();

    public static void main(String[] args) {

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    if (val >= Max) {
                        break;
                    }
                    synchronized (ox) {
                        list1.add(++val);
                        System.out.println("a>  " + val);
                        ox.notifyAll();
                        try {
                            if (val >= Max) {
                                // System.out.println("t1 run finished");
                                // Thread.currentThread().interrupt();
                                break;
                            }
                            Thread.sleep(1000);
                            ox.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }
                // Unreachable code
                // System.out.println("t1 run finished");

            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    if (val >= Max) {
                        break;
                    }
                    synchronized (ox) {
                        list2.add(++val);
                        System.out.println("b>  " + val);
                        ox.notifyAll();
                        try {
                            if (val >= Max) {
                                break;
                            }
                            Thread.sleep(1000);
                            ox.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        });

        Thread t3 = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    if (val >= Max) {
                        break;
                    }
                    synchronized (ox) {
                        list3.add(++val);
                        System.out.println("c> " + val);
                        ox.notifyAll();
                        try {
                            if (val >= Max) {
                                break;
                            }
                            Thread.sleep(1000);
                            ox.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        });

        Thread t4 = new Thread(new Runnable() {
            public void run() {
                while (true) {
                    if (val >= Max) {
                        break;
                    }
                    synchronized (ox) {
                        list4.add(++val);
                        System.out.println("d> " + val);
                        ox.notifyAll();
                        try {
                            if (val >= Max) {
                                break;
                            }
                            Thread.sleep(1000);
                            ox.wait();
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        });

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        try {
            t1.join();
            t2.join();
            t3.join();
            t4.join();
        } catch (Exception e) {
        }

        System.out.print("List1 has > ");
        for (Object o : list1) {
            System.out.print((Integer) o + ",");
        }

        System.out.println("");
        System.out.print("List2 has > ");
        for (Object o : list2) {
            System.out.print((Integer) o + ",");
        }

        System.out.println("");
        System.out.print("List3 has > ");
        for (Object o : list3) {
            System.out.print((Integer) o + ",");
        }

        System.out.println("");
        System.out.print("List4 has > ");
        for (Object o : list4) {
            System.out.print((Integer) o + ",");
        }
    }
}
4

2 回答 2

0

为什么要重新发明轮子?新的 Java SE 7 提供了Fork\Join framework,它可以同时为您完成这项工作。

于 2013-03-20T21:37:29.717 回答
0

添加一个指示当前线程轮次的字段怎么样?

static int turn = 0;

看看代码

同步细节

线程同步分为三个部分。

1) 首先,线程必须在 处获得锁synchronized (ox)。线程处于阻塞状态,直到持有者线程释放锁,然后线程尝试获取锁。如果再次获取锁失败,则再次进入阻塞状态。

2)当线程获取锁并进入 的块时synchronized,首先要判断它是否真的能够获取锁或等待某个操作完成。因此,我们有一个循环来检查轮到线程是否轮到。如果不是,线程将自己置于等待状态,说“我必须等待轮到完成任务的那个”。然后线程保持在等待状态,直到另一个线程用notifyAll. 然后它重新确定它是否能够完成这项工作,如果不能,它再次将自己置于等待状态。否则,它会完成它的工作。

3)最后,线程在完成其任务后不会忘记唤醒其他等待线程。notfiyAll如果它忘记了,其他线程将永远处于等待状态。这种状态称为死锁,可能会导致程序挂起。

于 2013-03-20T21:52:12.453 回答