Java并发:一些帮助

时间:2014-05-14 07:22:46

标签: java multithreading

我有一个这样的课程:

package crossRoadConcurency;

import java.util.List;

public class TourGuide 
{
    private volatile boolean isGuiding;
    private volatile boolean isInShop;
    private final Object lockObject = new Object();
    private final int id;

    public TourGuide(int id)
    {
        this.isGuiding=false;
        this.isInShop=false;
        this.id=id;
    }

    public synchronized boolean isFree()
    {
        return !isGuiding && !isInShop;
    }

    public void guide(final Tourist[] tourists)
{
    new Thread(new Runnable() 
    {   
        @Override
        public void run() 
        {
            synchronized (lockObject) 
            {
                while(!isFree()) 
                {
                    try 
                    {
                        System.out.println("Guide "+id+" is bussy. Waiting... ");
                        lockObject.wait();
                    } 
                    catch (InterruptedException e) 
                    {
                        e.printStackTrace();
                    }
                }
            }
            isGuiding=true;
            System.out.println("Guide "+id+" is guiding "+tourists.length+" tourists");
            try 
            {
                Thread.sleep(4000);//lets not wait one hour, shall we?
                for (Tourist tourist : tourists) 
                {
                    tourist.exit();
                }
                System.out.println("All tourists exited for guide "+id+". Going to shop");
                isInShop=true;
                isGuiding=false;//if we invert the way we give these values bad thing may happen
                Thread.sleep(4000);
                isInShop=false;
                System.out.println("Guide "+id+" is free");
                synchronized (lockObject) 
                {
                    lockObject.notifyAll();
                }
            } 
            catch (InterruptedException e) 
            {
                e.printStackTrace();
            }   

        }
    }).start();
}
}

另一堂课:

package crossRoadConcurency;

import java.util.Random;

public class Tourist 
{
    public void exit() throws InterruptedException
    {
        Random random = new Random();
        Thread.sleep(random.nextInt(1000));// max one second to exit
    }
}

我使用的是这样的:

package crossRoadConcurency;

import java.util.List;

public class Main 
{

    public static void main(String[] args) throws InterruptedException
    {
        Tourist[] tourists = new Tourist[20];
        for (int i=0;i<tourists.length;i++) 
        {
            tourists[i]=new Tourist();
        }
        TourGuide guide = new TourGuide(0);
        guide.guide(tourists);
            Thread.sleep(500);
        guide.guide(tourists);

    }

}

问题是我得到了这个输出:

Guide 0 is guiding 20 tourists
All tourists exited for guide 0. Going to shop
Guide 0 is free
Exception in thread "Thread-0" Guide 0 is guiding 20 tourists
java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at crossRoadConcurency.TourGide$1.run(TourGide.java:60)
    at java.lang.Thread.run(Unknown Source)
All tourists exited for guide 0. Going to shop
Guide 0 is free
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
    at java.lang.Object.notifyAll(Native Method)
    at crossRoadConcurency.TourGide$1.run(TourGide.java:60)
    at java.lang.Thread.run(Unknown Source)

第一个问题:为什么我没有看到“等待输出”
第二个问题:为什么我会收到例外
第三个问题:有没有更好的方法来做到这一点,因为我相当肯定这个概念已经混淆了

2 个答案:

答案 0 :(得分:1)

  1. 你没有看到&#34;等待&#34;因为您的指南默认是免费的。只在!isGuide && !isInShop时打印时!isFree()返回true。

  2. 您应该致电lockObject.notifyAll()。默认情况下,默认情况下直接调用notifyAll()会调用此对象,但您确实没有实现Runnable接口的无效对象的监视器,因为您从未通过调用synchroized(this)来执行此操作。这就是你获得例外的原因。

  3. 是。您应该使用Executor,例如SingleThreadExecutor和并发队列。除非您继续进行高性能计算,否则这是实现并发的强大而简单的方法。该套餐还提供了极好的功能和支持实用课程。查看java.util.concurrent

  4. 顺便说一下,你的包名包含大写字母,这是java编程规范不推荐的。

答案 1 :(得分:-1)

当我们同步任何块或方法时,我们应该同步类锁或对象锁。

但是你已经锁定了一些与该方法的调用者无关的对象

所以请将此更改从synchronized (lockObject)更改为以下内容并运行

synchronized (this)