我有2个矩阵和我需要乘他们然后打印的结果每个单元。只要一个细胞已准备好,我需要打印,但例如,我需要打印[0][0]细胞细胞之前[2][0]即使结果[2][0]准备好第一次。所以我需要打印出来的顺序。所以我的想法是要使打印机的螺纹等到 multiplyThread 通知它,正确的细胞是随时可以打印然后 printerThread 将打印的小区和回去等等。

所以我有这个线,不乘法运算:

public void run() 
{
    int countNumOfActions = 0; // How many multiplications have we done
    int maxActions = randomize(); // Maximum number of actions allowed

    for (int i = 0; i < size; i++)
    {       
        result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
        countNumOfActions++;
        // Reached the number of allowed actions
        if (countNumOfActions >= maxActions)
        {
            countNumOfActions = 0;
            maxActions = randomize();
            yield();
        }   
    }
    isFinished[rowNum][colNum] = true;
    notify();
}

螺纹,指纹的结果每个单元:

public void run()
{
    int j = 0; // Columns counter
    int i = 0; // Rows counter
    System.out.println("The result matrix of the multiplication is:");

    while (i < creator.getmThreads().length)
    {
        synchronized (this)
        {
            try 
            {
                this.wait();
            } 
            catch (InterruptedException e1) 
            {
            }
        }
        if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
        {
            if (j < creator.getmThreads()[i].length)
            {
                System.out.print(creator.getResult()[i][j] + " ");
                j++;
            }
            else
            {
                System.out.println();
                j = 0;
                i++;
                System.out.print(creator.getResult()[i][j] + " ");
            }
        }
    }

现在它引发了我这些情况例外:

Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at multiplyThread.run(multiplyThread.java:49)

49在 multiplyThread 是"通知()"..我觉得我需要使用同步的方式不同,但我不知道如何。

如果有人能帮助这个代码的工作,我将非常感谢它。

有帮助吗?

解决方案

能呼叫 通知() 你需要同步上相同的对象。

synchronized (someObject) {
    someObject.wait();
}

/* different thread / object */
synchronized (someObject) {
    someObject.notify();
}

其他提示

在使用时 waitnotify 或者 notifyAll Java 中的方法必须记住以下几点:

  1. 使用 notifyAll 代替 notify 如果您预计有多个线程正在等待锁。
  2. waitnotify 方法必须在同步上下文中调用. 。请参阅链接以获取更详细的说明。
  3. 始终致电 wait() 循环中的方法,因为如果多个线程正在等待锁,其中一个线程获得了锁并重置了条件,那么其他线程唤醒后需要检查条件,看看是否需要再次等待或可以开始处理。
  4. 使用同一个对象来调用 wait()notify() 方法;每个对象都有自己的锁,因此调用 wait() 在对象 A 上和 notify() 对对象 B 没有任何意义。

你需要穿这个吗?我想知道有多大你的矩阵,以及是否有任何受益于在具有一线打印,而其他不乘法运算。

或许这将是值得的测量之前的这段时间这样做比较复杂的线的工作?

如果你需要线,我将建立'n'线进行的乘法运算的细胞(也许'n'是数量的核可供您使用),然后使用 ExecutorService未来 机构派遣的多次乘法的同时进行。

这样你可以优化工作的基础上的数量的核心,你正在使用的高级别Java螺纹刀具(这应该让生活更容易).写信的结果回到一个接收矩阵,然后简单的打印本,一旦所有未来的任务已经完成。

让我们假设你有使用具有方法BlackBoxClass一些类名为doSomething();“黑盒子”的应用程序。

此外,你有观察者或听众命名onResponse(String resp)将由BlackBoxClass未知的时间后调用。

的流动是简单的:

private String mResponse = null; 
 ...
BlackBoxClass bbc = new BlackBoxClass();
   bbc.doSomething();
...
@override
public void onResponse(String resp){        
      mResponse = resp;       
}

比方说,我们不知道是怎么回事,有BlackBoxClass,当我们应该得到的答案,但你不希望继续你的代码,直到你得到的答案或其他搭话onResponse电话。这里进入 '同步助手':

public class SyncronizeObj {
public void doWait(long l){
    synchronized(this){
        try {
            this.wait(l);
        } catch(InterruptedException e) {
        }
    }
}

public void doNotify() {
    synchronized(this) {
        this.notify();
    }
}

public void doWait() {
    synchronized(this){
        try {
            this.wait();
        } catch(InterruptedException e) {
        }
    }
}
}

现在我们可以实现我们想要的:

public class Demo {

private String mResponse = null; 
 ...
SyncronizeObj sync = new SyncronizeObj();

public void impl(){

BlackBoxClass bbc = new BlackBoxClass();
   bbc.doSomething();

   if(mResponse == null){
      sync.doWait();
    }

/** at this momoent you sure that you got response from  BlackBoxClass because
  onResponse method released your 'wait'. In other cases if you don't want wait too      
  long (for example wait data from socket) you can use doWait(time) 
*/ 
...

}


@override
public void onResponse(String resp){        
      mResponse = resp;
      sync.doNotify();       
   }

}

您只能打电话通知你在哪里拥有自己的监控对象。所以,你需要像

synchronized(threadObject)
{
   threadObject.notify();
}

notify()需要尽可能很好地同步

我会正确的简单例子演示了使用waitnotify在Java中正确的方式。 因此,我将创建一个名为的ThreadA ThreadB 两类。 ThreadA中会调用ThreadB。

public class ThreadA {
    public static void main(String[] args){
        ThreadB b = new ThreadB();//<----Create Instance for seconde class
        b.start();//<--------------------Launch thread

        synchronized(b){
            try{
                System.out.println("Waiting for b to complete...");
                b.wait();//<-------------WAIT until the finish thread for class B finish
            }catch(InterruptedException e){
                e.printStackTrace();
            }

            System.out.println("Total is: " + b.total);
        }
    }
} 

和为类ThreadB:

class ThreadB extends Thread{
    int total;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
                total += i;
            }
            notify();//<----------------Notify the class wich wait until my    finish 
//and tell that I'm finish
            }
        }
    }

我们可以调用通知恢复等待对象的执行如

public synchronized void guardedJoy() {
    // This guard only loops once for each special event, which may not
    // be the event we're waiting for.
    while(!joy) {
        try {
            wait();
        } catch (InterruptedException e) {}
    }
    System.out.println("Joy and efficiency have been achieved!");
}

通过调用通知上同一类的另一个目的恢复此

public synchronized notifyJoy() {
    joy = true;
    notifyAll();
}

简单的使用,如果你想如何或者执行线程: -

public class MyThread {
    public static void main(String[] args) {
        final Object lock = new Object();
        new Thread(() -> {
            try {
                synchronized (lock) {
                    for (int i = 0; i <= 5; i++) {
                        System.out.println(Thread.currentThread().getName() + ":" + "A");
                        lock.notify();
                        lock.wait();
                    }
                }
            } catch (Exception e) {}
        }, "T1").start();

        new Thread(() -> {
            try {
                synchronized (lock) {
                    for (int i = 0; i <= 5; i++) {
                        System.out.println(Thread.currentThread().getName() + ":" + "B");
                        lock.notify();
                        lock.wait();
                    }
                }
            } catch (Exception e) {}
        }, "T2").start();
    }
}
  

响应: -

T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B
T1:A
T2:B

对于这个特定的问题,为什么不是你的各种结果当最后你的线程的处理,你可以在任何你想要的格式打印保存起来变量,然后。这是,如果你要使用你的工作经历在其他项目中特别有用。

这看起来像生产者 - 消费者图案的情况。如果你正在使用Java 5或者,你可以考虑使用阻塞队列(java.util.concurrent.BlockingQueue中),并留下线程协同工作的基本框架/ API实现。 请参阅从实例 Java 5中: http://docs.oracle.com /javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html 或Java 7(同示例): http://docs.oracle.com/javase /7/docs/api/java/util/concurrent/BlockingQueue.html

您已经适当的防护您的代码块当您使用wait()调用synchronized(this)方法。

但是,当调用方法notify()不使用防护块还没有采取预防措施相同:synchronized(this)synchronized(someObject)

如果你指的是Oracle文档页面上对象类,它包含wait()notify()notifyAll()方法,你可以看到下面的预防措施在所有这三种方法

  

此方法应该仅由一个线程,它是此对象监视器的拥有者被称为

许多事情已经过去7年了变化,让我们看看到其他替代品synchronized下面SE问题:

为什么如果可以使用一个的ReentrantLock使用同步(本)?

同步VS锁

避免同步(本)中的Java?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top