假设抽奖箱中有100个号码(依次从1到100),开启两个线程, 共随机抽选出10个号码,并在控制台上打印出两个线程分别抽选了哪些号码? 提示:(两个线程不能抽取同一个号码,已经抽取的号码不能再次抽取; 不限定两个线程抽取的个数一样,总共抽选10个即可,线程名自定义)。
问题是,我按照多线程的正规写法用了同步代码块,锁对象也是类的字节码文件,但是输出的时候每次只有一个线程进行输出,用了sleep()方法也切换不了线程,求助哪里出了问题?下面是代码:
public class ChouJiang {public static void main(String[] args) {
Thread t1 = new Chou();
t1.setName("线程一");
Thread t2 = new Chou();
t2.setName("线程二");t1.start();
t2.start();
}}class Chou extends Thread {
// 100个号码(依次从1到100)static ArrayList<Integer> list = new ArrayList<Integer>();
static HashSet<Integer> hs = new HashSet<Integer>();
static {for (int i = 1; i <= 100; i++) {
list.add(i);
}while (hs.size() < 10) {
Random r = new Random();
int j = r.nextInt(100) + 1; // 随机数获取1-100
hs.add(j);
}
}@Override
public void run() {
// 共随机抽选出10个号码, 并在控制台上打印出两个线程分别抽选了哪些号码
// * 提示:(两个线程不能抽取同一个号码,已经抽取的号码不能再次抽取;
synchronized (ChouJiang.class) {
while (list.size() > 90) {
for (Integer num : hs) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()
+ "抽取了:" + num + "号球");
list.remove(num);
} catch (Exception e) {
}}}
}}}
类采用的是继承Thread,怀疑是不是创建了两个Thread,出现了两个对象的问题,但是用了实现runnable接口结果还是一样的。

解决方案 »

  1.   

    把代码的这部分添加一条输出.然后看看输出结果.
    然后好好考虑下为什么会是这样.相信你会弄明白的.如果实在还是不明白的话可以再提问.
    主要还是你需要实现的结果和你代码的逻辑不符合的原因@Override
    public void run() {
    // 共随机抽选出10个号码, 并在控制台上打印出两个线程分别抽选了哪些号码
    // * 提示:(两个线程不能抽取同一个号码,已经抽取的号码不能再次抽取;
    synchronized (ChouJiang.class) {
    System.out.printf("进入线程:%s\n",Thread.currentThread().getName());
      

  2.   

    按照现在的逻辑,线程1会先取出10个数字,然后线程2进入到同步块里面去,结果发现list.size=90然后就没进while循环直接结束
      

  3.   

    没必要加while (list.size() > 90) 判断
      

  4.   

    稍微改了一下,两个问题:1.锁的位置不对;2.set集合用的不太好 import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.Random; public class Test{
    public static void main(String[] args) {
    Thread t1 = new Chou();
    t1.setName("线程一");
    Thread t2 = new Chou();
    t2.setName("线程二"); t1.start();
    t2.start();
    } } class Chou extends Thread {
    // 100个号码(依次从1到100) static ArrayList<Integer> list = new ArrayList<Integer>();
    static ArrayList<Integer> hs = new ArrayList<Integer>();
    static { for (int i = 1; i <= 100; i++) {
    list.add(i);
    } while (hs.size() < 10) {
    Random r = new Random();
    int j = r.nextInt(100) + 1; // 随机数获取1-100
    hs.add(j);
    }
    } @Override
    public void run() {
    // 共随机抽选出10个号码, 并在控制台上打印出两个线程分别抽选了哪些号码
    // * 提示:(两个线程不能抽取同一个号码,已经抽取的号码不能再次抽取;
    while (list.size() > 90) {
    // for (Integer num : hs) {
    synchronized (Test.class) {
    try {
    Thread.sleep(50);
    System.out.println(Thread.currentThread().getName()
    + "抽取了:" + hs.get(0) + "号球");
    list.remove(hs.get(0));
    hs.remove(0);
    } catch (Exception e) {

    } // } }
    } } }