Hallo,
een tijd terug heb ik in Java een programma geschreven wat afbeeldingen in een bepaalde map resized en in een nieuwe map op slaat. Dit werkt allemaal goed alleen vond ik het nogal langzaam dus besloot ik om het multithreaded te maken.
Deze refactoring is bijna klaar maar ikz it nog met een klein probleem. Ik lees eerst een directory en zet alle jpg files in deze directory in een vector. Deze vector deel ik vervolgens in een aantal sublists (het aantal sublists is afhankelijk van het aantal processoren). deze sublists worden ieder in een eigen thread gebruikt om afbeeldingen te kunnen resizen.
Als ik echter twee of meer threads ga starten krijg ik een raar fenomeen. De twee threads starten en de eerste paar files worden omgezet en opgeslagen en op een bepaald moment kapt de laatst gestarte thread ermee met als resultaat dat iets meer dan de helft (even vanuit gaande dat we het over 2 threads hebben) van de files zijn geresized en niet zoals verwacht allemaal.
Ik maak gebruik van de volgende code om subthreads aan te maken
in elke ResizeJob wordt de volgende code uitgevoerd
Ik dacht eerst dat het een simpel geval van deadlocking was maar de twee threads delen helemaal geen resources dus volgens mij kan het dat niet zijn. Wie kan mij helpen met dit probleem(pje)
een tijd terug heb ik in Java een programma geschreven wat afbeeldingen in een bepaalde map resized en in een nieuwe map op slaat. Dit werkt allemaal goed alleen vond ik het nogal langzaam dus besloot ik om het multithreaded te maken.
Deze refactoring is bijna klaar maar ikz it nog met een klein probleem. Ik lees eerst een directory en zet alle jpg files in deze directory in een vector. Deze vector deel ik vervolgens in een aantal sublists (het aantal sublists is afhankelijk van het aantal processoren). deze sublists worden ieder in een eigen thread gebruikt om afbeeldingen te kunnen resizen.
Als ik echter twee of meer threads ga starten krijg ik een raar fenomeen. De twee threads starten en de eerste paar files worden omgezet en opgeslagen en op een bepaald moment kapt de laatst gestarte thread ermee met als resultaat dat iets meer dan de helft (even vanuit gaande dat we het over 2 threads hebben) van de files zijn geresized en niet zoals verwacht allemaal.
Ik maak gebruik van de volgende code om subthreads aan te maken
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| ExecutorService exec = (ExecutorService) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); Vector<File> files = this.sourceDirectory.list(new ImageFileFilter()); if(files.size() > 0) { this.setChanged(); this.notifyObservers(new ProgressMessage(String.valueOf(files.size()),ProgressMessage.STATUS_FILECOUNT)); if(!this.destinationDirectory.exists()) { this.destinationDirectory.mkdir(); } if(!this.thmbDestinationDirectory.exists()) { this.thmbDestinationDirectory.mkdir(); } int modulo = files.size() % maxSlices; int sliceSize = (files.size()-modulo)/maxSlices; lBound = modulo; uBound = sliceSize; for(int i = 0; i < maxSlices;i++) { System.out.println("lBound :"+lBound+" - "+uBound); exec.submit(new ResizeJob(new Vector(files.subList(lBound,uBound)),this.percentage,this.thumbPercentage,this.quality,this.destinationDirectory,i,this)); lBound = uBound; uBound = uBound + sliceSize; } }else{ this.setChanged(); this.notifyObservers(MultiThreadedImageHandler.MSG_DONE); } |
in elke ResizeJob wordt de volgende code uitgevoerd
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
| BufferedImage thumb, dst, src; Graphics2D dstGraphics, thumbGraphics; int w,h,wThumb,hThumb; for(Iterator it = this.files.iterator(); it.hasNext();) { System.out.println(this.number + " processing file :"+i+" of "+this.files.size()); File f = (File) it.next(); System.out.println(f.toString()); if(f.exists() && f.isFile()) { System.out.println("doing"); try { src = ImageIO.read(f); w = Integer.parseInt(String.valueOf((src.getWidth()/100)*scale)); h = Integer.parseInt(String.valueOf((src.getHeight()/100)*scale)); dst = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); dstGraphics = dst.createGraphics(); dstGraphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); dstGraphics.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY); dstGraphics.drawImage(src, 0, 0, w, h, null); File resFile = new File(this.destination.getAbsolutePath()+"/"+f.getName()); File thumbFile = new File(this.destination.getAbsolutePath()+"/thumbs/"); wThumb = Integer.parseInt(String.valueOf((src.getWidth()/100)*scaleThumb)); hThumb = Integer.parseInt(String.valueOf((src.getHeight()/100)*scaleThumb)); thumb = new BufferedImage(wThumb,hThumb,BufferedImage.TYPE_INT_RGB); thumbGraphics = thumb.createGraphics(); thumbGraphics.drawImage(dst,0,0,wThumb,hThumb,null); thumbFile = new File(this.destination.getAbsolutePath()+"/thumbs/"+f.getName()); System.out.println("write it"); ImageIO.write(thumb, "JPG", thumbFile); ImageIO.write(dst, "JPG", resFile); thumb.flush(); dst.flush(); } catch (Exception e) { System.out.println("Error"+e.toString()); System.out.println(e.getMessage()); } } i++; } |
Ik dacht eerst dat het een simpel geval van deadlocking was maar de twee threads delen helemaal geen resources dus volgens mij kan het dat niet zijn. Wie kan mij helpen met dit probleem(pje)