2013-08-06 78 views
2

我在我的代码中有一个线程问题,应该不会发生 - 但是。所以我正在尝试做一些工作。我会尽量解释我的问题,简单的代码,我可以 - 因为我遇到问题的代码是大,所以在短的代码复杂 :java并发 - 同步块

................... 
.................. 
void createAndRunThreads(){ 
    List<Path> pathList = //read path from DB readPath(); 
    for(Path p : pathList){ 
     RunJob rj = new RunJob(p); 
     Thred t = new Thread(rj); 
     t.start(); 
    } 
} 

class RunJob implements Runnable { 
    private Path path; 
    private ExecuteJob execJob; 

    public RunJob(Path path){ 
     this.path = path; 
     this.execJob = new ExecuteJob(); 
    } 

    public void run() { 
     execJob.execute(path); 
    } 

} 

class ExecuteJob { 

    private static Job curentExecutingJob; 

    public void execute(Path path){ 
     //here every thread should get different job list from others but this is not happening 
     //so what happens eventually two threads are executing the same Job at once and it gets messy 
     List<Job> jobList = getJobsFromPath(path); 

     for(Job job : jobList) { 
     curentExecutingJob=job; 

     //work around that I'm trying to do. So if other thread tries to run the same job has to wait on lock(I dont know if this is posible do) 
     synchronized(curentExecutingJob){ 
      if(job.getStatus.equals("redy")){ 
       //do sum initialization 
       //and databese changes 
       job.run(); 
      } 
     } 
     } 
    } 

} 

所以我担心的是,如果这会工作 - 我不知道是否锁内的对象是通过内存(需要是确切的对象)或等于(实现相等)

当静态的curentExecutingJob成员有一个值对象在第一个线程和创建的锁(在同步块)和第二个线程的变化值和尝试进入同步块(我期望,我希望是线程2将继续执行和onl Ÿ时间,这将是块时,他会得到DB以前第一个线程得到它)

相同的工作,我不知道这种方法可以做到的,有意识

两个线程都运行下面的代码即内部方法

1 Job j = getJobByIdFromDB(1111); 
2 if(j.status.equals("redye")){ 
3  do staff 
4  make database changes 
5  j.run(); 
6  j.state="running"; 
7 } 

的的ThreadA是从JVM在3行执行停止和他的状态从运行到可运行改变,并且被设置在所述轮询等待。

ThreadB由JVM给出机会,ThreadB执行我不想发生的行1,2,3,4,5,6。我想第2,3行输入代码的第一个线程在其他线程的某个人有机会输入相同的代码之前完成

问题完成这个问题是两个线程正在执行不同实例的示例方法同步整个方法不会工作 - 也有其他代码已执行此方法,我不希望这是同步到
所以有解决我的问题 此外,如果我让同步(this.class) {}它将失去多线程的好处和意义

+0

那么,首先,你的变量curentExecutingJob被声明为静态的,并且会被同时覆盖和访问。这种方法并不是很好。你期望用这个方案完成什么? – Martin

+0

你考虑过一个ExecutorService吗?它是一个带有队列的线程池,它确保每个任务仅由一个线程运行。 –

回答

0

无法评论,所以我会把它作为答案。抱歉。

同步(curentExecutingJob)

将在对象curentExecutingJob同步(在你的术语,存储器)。如果使用currentExecutingJob.equals(otherExecutingJob)== true同步另一个对象otherExecutingJob,则两个同步语句不会相互影响。

对于你的问题/问题:如果你描述getJobsFromPath正在做什么或应该做什么以及你实际想要做什么以及你的问题实际是什么,这将会很有帮助。这对我来说并不是很清楚。

+0

我想他想要同步实际上改变同一个对象的线程,并且在那里遇到一些麻烦,当他们试图编辑相同的对象以使它们按某种顺序同步时,他想同步所有的线程...... –

0

我看到你的代码,它检查的作业的状态,如果是准备好了没有,还有,我想这不是一个afeasible方式

,你可以用它代替了Runnable

可调用接口

这里有一个详细的例子可以帮助你。

Java Concurrency

1

的问题是,“currentExecutingJob”被定义为静态的,这意味着ExecuteJob的所有实例共享该变量的相同的“实例”。此外,您正在将该变量的值设置为同步块之外,这意味着每个线程都将以不受控制的方式进行设置。您的以下同步块应该没有任何实际影响。

鉴于您的示例代码的编写方式,在我看来,您不需要任何静态变量,也不需要任何同步,因为没有多个线程共享资源。

但是,您在代码中的注释表明您希望防止两个线程同时执行相同的作业。你的代码没有达到这个目的,因为没有比较正在运行的作业来查看是否正在运行相同的作业,并且即使有比较,你的getJobsFromPath()也需要构造一个作业列表,使得相同的对象实例当两个线程/路径遇到相同的“工作”时需要重用。

我在代码中看不到任何这样的内容。