如何在java中同步方法?

时间:2011-10-26 08:23:00

标签: java multithreading

我有一些小问题。 我有一些类处理器进程流程类只有名称和值 处理器必须计算此值并显示它。反过来,处理器实现Runnable接口 但我遇到了麻烦。当我将进程设置为我的处理器时,它开始计算值,但我想启动具有不同进程值的另一个线程,并且此值也设置为第一个线程。 这是代码

    package ua.edu.lp.controller;

import java.util.Random;

import ua.edu.lp.controller.processors.FirstProcessor;
import ua.edu.lp.controller.processors.MyBaseProcessor;
import ua.edu.lp.model.MyProcess;
import ua.edu.lp.model.Queue;

public class Computer {

    private Queue<MyProcess> queue;

    public void run() {
        MyBaseProcessor myBaseProcessor = new FirstProcessor();
        generateQueue();

        for (int i = 0; i < queue.getQueue().size(); i++) {
            MyProcess process = queue.get(i);
            myBaseProcessor.setProcess(process);
            Thread thread = new Thread(myBaseProcessor);
             thread.start();
        }
    }

    private void generateQueue() {
        queue = new Queue<MyProcess>();
        for (int i = 0; i < 10; i++) {
            String name = "Process[" + (i + 1) + "]";
            MyProcess myProcess = new MyProcess(name,
                    new Random().nextInt(10) + 1);
            queue.add(myProcess);
            System.out.println(myProcess.getName() + "\t"
                    + myProcess.getValue());
        }
    }
}

BaseProcessor

package ua.edu.lp.controller.processors;

import ua.edu.lp.model.MyProcess;

public abstract class MyBaseProcessor implements Runnable {

    protected MyProcess myProcess;

    @Override
    public void run() {
        synchronized (myProcess) {
            calculateValue();
        }
    }

    protected abstract void calculateValue();

    public synchronized MyProcess getProcess() {
        return myProcess;
    }

    public synchronized void setProcess(MyProcess myProcess) {
        synchronized (myProcess) {
            this.myProcess = myProcess;
        }

    }

}

和FirstProcessor

package ua.edu.lp.controller.processors;

public class FirstProcessor extends MyBaseProcessor {

    @Override
    protected synchronized void calculateValue() {
        System.out.println("First processor is working...");
        int value = this.myProcess.getValue();
        int result = (int) Math.pow(value, 2);
        System.out.println("Pow of " + value + " = " + result);
        System.out.println("First processor is free");
    }

}

您可以从http://www.sendspace.com/file/5rlmkx

下载所有项目

4 个答案:

答案 0 :(得分:1)

这是巨大的代码....只需要编写代码.... 对于java中的同步....你可以看看..
Synchronization in java

答案 1 :(得分:1)

您的所有任务都是独立的,因此您不需要在任何地方进行同步。但是,你正在共享一个BaseProcessor对象,该对象在同步时,在处理的生命周期内不会同步。

您只需要同步处理共享数据,其中一个线程可以在线程启动后修改该数据。

BTW:我会使用ExecutorService,因为它将队列和线程池包装在一个类中。

我假设您的队列是线程安全的,因为并非所有队列都是Java。如果不是,那可能是个问题。


这个程序做同样的事情,但它的简单和线程安全。

ExecutorService service = Executors.newSingleThreadExecutor();
Random random = new Random();
for (int i = 0; i < 10; i++) {
    final String name = "Process[" + (i + 1) + "]";
    final int value = random.nextInt(10) + 1;
    service.execute(new Runnable() {
        @Override
        public void run() {
            System.out.println("First processor is working...");
            int result = (int) Math.pow(value, 2);
            System.out.println("Pow of " + value + " = " + result);
            System.out.println("First processor is free");
        }
    });
    System.out.println(name + "\t" + value);
}
service.shutdown();

答案 2 :(得分:1)

使处理器无状态 - 删除字段进程并执行以下操作:

final Processor processor = new Processor();

processor.process(new Process(...));

public void process( final Process process ) {
    new Thread(new Runnable() {
        //do somethig with process
        }).run();
}

注意:处理器必须只执行常见任务 - 运行流程,处理实现业务逻辑,只处理您已完成的计算。

答案 3 :(得分:1)

synchronized(myProcess)

只会为myProcess对象设置MUTEX。只有当两个对象都指向同一个myProcess对象时,不同MyBaseProcessor对象之间的同步才会起作用。

我不知道具体要求是什么,但看起来对我来说是正确的=&gt;一个处理器只能处理一个进程吗?

对我来说有点困惑的是你为什么要在setterMethod setProcess(..)中与目标字段同步。这没有任何效果。

也许您不明白同步将使用对象而不是类型?

BR - 迈克尔