在java中锁定线程不起作用

时间:2014-07-11 15:30:15

标签: java multithreading synchronization locks

我有一个简单的多线程问题,我只是想弄清楚。我尝试了同步方法和使用锁,但没有一个工作,所以我希望有人可以帮助我。

public void startThreads(ArrayList<ArrayList<Tocka>> pLista) {
        ScheduledThreadPoolExecutor eventPool = new ScheduledThreadPoolExecutor(pLista.size());
            for(int i=0; i<pLista.size(); i++) {
                eventPool.execute(new Dretva(pLista.get(i),i));
            }
    }

public synchronized void run() {
        lock.lock();
        System.out.print(this.id + ". ");
        optimalnost.printOrder(this.lista);
        double distance = optimalnost.getDistanceList(this.lista);
        System.out.println(" - " + distance);
        System.out.println();
        checkMin(distance);
        lock.unlock();
    }

我从测试类startThreads方法调用List列表(startThreads和thread在分离的类中)。在类Dretva(线程)中,我有一个运行代码,它使用list执行一些计算,它作为参数传递并打印计算。在我的例子中有6个列表,我试图通过所有这些,但当时只有一个。当我不使用线程时,它可以正常工作,但是对于这样的线程,我会搞砸并改组输出。

我需要帮助如何在活动线程未完成时让其他线程等待。

以下是我的问题的截图:

enter image description here

2 个答案:

答案 0 :(得分:4)

synchronized方法在该对象上同步,而不是全局同步。

只需传入一个对象并同步:

public void startThreads(ArrayList<ArrayList<Tocka>> pLista) {
    final Object lockOb = new Object();

    ScheduledThreadPoolExecutor eventPool = new ScheduledThreadPoolExecutor(pLista.size());
        for(int i=0; i<pLista.size(); i++) {
            eventPool.execute(new Dretva(lockOb, pLista.get(i),i));
        }
}

Object lockOb;

public void run() {
    synchronized(lockOb) {
       System.out.print(this.id + ". ");
       optimalnost.printOrder(this.lista);
       double distance = optimalnost.getDistanceList(this.lista);
       System.out.println(" - " + distance);
       System.out.println();
       checkMin(distance);
    }
}       

现在所有对象共享一个锁对象并且都在同步,因此一次只能运行一个。虽然你已经创建了很多线程,但是故意这样做完全打败了使用线程的点,所以故意只做其中一个线程就可以执行。

作为旁注,您应该始终使用try finally块来处理需要解锁的任何类型的锁定对象。

答案 1 :(得分:1)

您的同步方法run是一种成员方法。这意味着您正在同步对象的实例。由于您创建了多个实例,因此每个实例都在另一个对象上获取锁定。如果希望跨实例同步访问,则必须明确提供互斥锁以锁定或使用静态常量互斥锁来同步所有实例。