在递归块挂起中使用CountDownLatch和Object.wait(Using CountDownLatch & Object.wait inside recursive block hangs)
问题:在尝试以分阶段方式检索递归块内的值时,执行会挂起。
描述:
CountDownLatch
和Object.wait
用于实现递归块内的值的分阶段方式访问。 但是,该程序挂起以下输出:2 < 16 3 < 16 4 < 16 5 < 16 Current total: 5 Inside of wait Inside of wait
程序:
import java.util.concurrent.*; public class RecursiveTotalFinder { private static CountDownLatch latch1; private static CountDownLatch latch2; private static CountDownLatch latch3; public static void main(String... args) { latch1 = new CountDownLatch(1); latch2 = new CountDownLatch(1); latch3 = new CountDownLatch(1); //Create object TotalFinder tf = new TotalFinder(latch1,latch2,latch3); //Start the thread tf.start(); //Wait for results from TotalFinder try { latch1.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 5th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); //Wait for results again try { latch2.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 10th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); //Wait for results again try { latch3.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 15th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); } } class TotalFinder extends Thread{ CountDownLatch tfLatch1; CountDownLatch tfLatch2; CountDownLatch tfLatch3; private static int count = 1; private static final class Lock { } private final Object lock = new Lock(); private boolean gotSignalFromMaster = false; public TotalFinder(CountDownLatch latch1, CountDownLatch latch2, CountDownLatch latch3) { tfLatch1 = latch1; tfLatch2 = latch2; tfLatch3 = latch3; } public void run() { findTotal(16); } //Find total synchronized void findTotal(int cnt) { if(count%5==0) { if(count==5) tfLatch1.countDown(); if(count==10) tfLatch2.countDown(); if(count==15) tfLatch3.countDown(); //Sleep for sometime try { Thread.sleep(3000); } catch(InterruptedException ie) { ie.printStackTrace(); } //Wait till current total is printed synchronized(lock) { while(gotSignalFromMaster==false) { try { System.out.println(" Inside of wait"); lock.wait(); } catch(InterruptedException ie) { ie.printStackTrace(); } } System.out.println("Came outside of wait"); } } count +=1; if(count < cnt) { System.out.println(count +" < "+cnt); findTotal(cnt); } } //Return the count value public int getCurrentTotal() { return count; } //Release lock public void releaseWaitLock() { //Sleep for sometime try { Thread.sleep(5000); } catch(InterruptedException ie) { ie.printStackTrace(); } synchronized(lock) { gotSignalFromMaster=true; lock.notifyAll(); } } //Reset wait lock public void resetWaitLock() { gotSignalFromMaster = false; } }
分析:在我的初步分析中,看起来等待是以递归方式发生的,尽管从主程序调用了
notifyAll
。帮助:为什么在
CountDownLatch
没有生效后使用notfiyAll
进行免费锁定? 需要某人帮助了解此计划中究竟发生了什么。Problem: While trying to retrieve values inside a recursive block in a phased manner, the execution gets hung.
Description:
CountDownLatch
&Object.wait
are used to achieve the phased manner access of value inside the recursive block. But, the program hangs with following output:2 < 16 3 < 16 4 < 16 5 < 16 Current total: 5 Inside of wait Inside of wait
Program:
import java.util.concurrent.*; public class RecursiveTotalFinder { private static CountDownLatch latch1; private static CountDownLatch latch2; private static CountDownLatch latch3; public static void main(String... args) { latch1 = new CountDownLatch(1); latch2 = new CountDownLatch(1); latch3 = new CountDownLatch(1); //Create object TotalFinder tf = new TotalFinder(latch1,latch2,latch3); //Start the thread tf.start(); //Wait for results from TotalFinder try { latch1.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 5th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); //Wait for results again try { latch2.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 10th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); //Wait for results again try { latch3.await(); } catch(InterruptedException ie) { ie.printStackTrace(); } //Print the result after 15th iteration System.out.println("Current total: "+tf.getCurrentTotal()); tf.releaseWaitLock(); tf.resetWaitLock(); } } class TotalFinder extends Thread{ CountDownLatch tfLatch1; CountDownLatch tfLatch2; CountDownLatch tfLatch3; private static int count = 1; private static final class Lock { } private final Object lock = new Lock(); private boolean gotSignalFromMaster = false; public TotalFinder(CountDownLatch latch1, CountDownLatch latch2, CountDownLatch latch3) { tfLatch1 = latch1; tfLatch2 = latch2; tfLatch3 = latch3; } public void run() { findTotal(16); } //Find total synchronized void findTotal(int cnt) { if(count%5==0) { if(count==5) tfLatch1.countDown(); if(count==10) tfLatch2.countDown(); if(count==15) tfLatch3.countDown(); //Sleep for sometime try { Thread.sleep(3000); } catch(InterruptedException ie) { ie.printStackTrace(); } //Wait till current total is printed synchronized(lock) { while(gotSignalFromMaster==false) { try { System.out.println(" Inside of wait"); lock.wait(); } catch(InterruptedException ie) { ie.printStackTrace(); } } System.out.println("Came outside of wait"); } } count +=1; if(count < cnt) { System.out.println(count +" < "+cnt); findTotal(cnt); } } //Return the count value public int getCurrentTotal() { return count; } //Release lock public void releaseWaitLock() { //Sleep for sometime try { Thread.sleep(5000); } catch(InterruptedException ie) { ie.printStackTrace(); } synchronized(lock) { gotSignalFromMaster=true; lock.notifyAll(); } } //Reset wait lock public void resetWaitLock() { gotSignalFromMaster = false; } }
Analysis: In my initial analysis it looks like the wait is happening recursively eventhough
notifyAll
is invoked from the main program.Help: Why free lock using
notfiyAll
after aCountDownLatch
didn't take effect? Need someone's help in understanding what exactly is happening in this program.
原文:https://stackoverflow.com/questions/29066020
最满意答案
正如您所暗示的,对您的问题最有用的功能是:
slice
。 您还应该阅读这篇Mathworks文章:Exploring Volumes with Slice Planes
因为它提供了有关如何使用切片的更多示例。在您的情况下,您拥有每个切片的数据(每个图像都是切片),您只需将它们打包在一起,因此Matlab会将它们解释为体积数据。
由于您没有提供任何样本数据,我必须生成一个小样本。 我将使用Matlab函数
flow
生成体积数据并从中提取4个图像(4个切片):%% Generate sample images [x,y,z,v] = flow; %// x,y,z and v are all of size [25x50x25] im1 = v(:,:,5); %// extract the slice at Z=5. im1 size is [25x50] im2 = v(:,:,10); %// extract the slice at Z=10. im2 size is [25x50] im3 = v(:,:,15); %// extract the slice at Z=15. im3 size is [25x50] im4 = v(:,:,20); %// extract the slice at Z=20. im4 size is [25x50] hf = figure ; subplot(221);imagesc(im1);title('Z=5'); subplot(222);imagesc(im2);title('Z=10'); subplot(223);imagesc(im3);title('Z=15'); subplot(224);imagesc(im4);title('Z=20'); %// This is just how I generated sample images, it is not part of the "answer" !
这给你4个简单的图像:
现在真的很有趣。 将所有图像堆叠在一个矩阵中,就像它们只是切片一样:
M(:,:,1) = im1 ; M(:,:,2) = im2 ; M(:,:,3) = im3 ; M(:,:,4) = im4 ;
你现在有一个矩阵
M [25x50x4]
。 如果你有太多的图像,你可以设计一个循环来堆叠它们 。从那以后,只需要调用
slice
即可获得所需的图片。 查看文档以探索所有可能的渲染选项。 一个简单的例子是:hf2 = figure ; hs = slice(M,[],[],1:4) ; shading interp set(hs,'FaceAlpha',0.8);
哪个产生:
注意:这使用默认索引,这应该适合您描述的问题(简单地堆叠一些图像)。 如果您希望您的音量具有真实坐标,则可以使用
ndgrid
构建坐标系。 例如:[xs,ys,zs] = ndgrid( 1:25 , 1:50 , 1:4 ) ;
将创建一个大小为
[25x50x4]
的网格/坐标系。 只需替换数字即可构建所需的网格坐标。As you got hinted, the most useful function for your problem is :
slice
. You should also have a good read at this Mathworks article:Exploring Volumes with Slice Planes
as it gives more examples on how to work with slice.In your case, you have the data for each of your slices (each image is a slice), you just need to pack them together so Matlab will interpret them as volumetric data.
Since you didn't give any sample data to work with, I have to generate a small sample. I will use the Matlab function
flow
to generate volumetric data and extract 4 images (4 slices) out of it:%% Generate sample images [x,y,z,v] = flow; %// x,y,z and v are all of size [25x50x25] im1 = v(:,:,5); %// extract the slice at Z=5. im1 size is [25x50] im2 = v(:,:,10); %// extract the slice at Z=10. im2 size is [25x50] im3 = v(:,:,15); %// extract the slice at Z=15. im3 size is [25x50] im4 = v(:,:,20); %// extract the slice at Z=20. im4 size is [25x50] hf = figure ; subplot(221);imagesc(im1);title('Z=5'); subplot(222);imagesc(im2);title('Z=10'); subplot(223);imagesc(im3);title('Z=15'); subplot(224);imagesc(im4);title('Z=20'); %// This is just how I generated sample images, it is not part of the "answer" !
Which gives you 4 simple images:
Now is the real fun. Stack all your images in one matrix as if they were just slices:
M(:,:,1) = im1 ; M(:,:,2) = im2 ; M(:,:,3) = im3 ; M(:,:,4) = im4 ;
You now have a matrix
M [25x50x4]
. If you have too many images you can work out a loop to stack them.From there on, it's just a simple matter of calling
slice
to get your desired picture. Look at the documentation to explore all the possible rendering options. A simple example is:hf2 = figure ; hs = slice(M,[],[],1:4) ; shading interp set(hs,'FaceAlpha',0.8);
Which produces:
note: This uses the default indexing, which should be good for the problem you describe (simply stacking some images). If you want your volume to have real coordinates, you can build a coordinate system with
ndgrid
. Ex:[xs,ys,zs] = ndgrid( 1:25 , 1:50 , 1:4 ) ;
will create a grid/coordinate system of size
[25x50x4]
. Just replace the numbers to build the grid coordinate you need.
相关问答
更多-
假设I是你的输入图像, F是它的傅立叶变换(即F = fft2(I) ) 你可以使用这个代码: F = fftshift(F); % Center FFT F = abs(F); % Get the magnitude F = log(F+1); % Use log, for perceptual scaling, and +1 since log(0) is undefined F = mat2gray(F); % Use mat2gray to scale the image between 0 an ...
-
正如您所暗示的,对您的问题最有用的功能是: slice 。 您还应该阅读这篇Mathworks文章: Exploring Volumes with Slice Planes因为它提供了有关如何使用切片的更多示例。 在您的情况下,您拥有每个切片的数据(每个图像都是切片),您只需将它们打包在一起,因此Matlab会将它们解释为体积数据。 由于您没有提供任何样本数据,我必须生成一个小样本。 我将使用Matlab函数flow生成体积数据并从中提取4个图像(4个切片): %% Generate sample imag ...
-
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
如果您实际查看plot 文档 ,您会看到如果您将矩阵传递给它,它会将每列绘制为相同轴上的单独绘图对象。 因此,您可以简单地将数据的转置传递给plot 。 % Example data A = magic(10); % Create a plot for each row hplot = plot(A.'); 这将使用下一个绘图颜色绘制每个信号。 如果要确保拥有所有不同的颜色,可以使用颜色图(例如parula )为每个绘图显式设置不同的颜色。 set(hplot, {'Color'}, num2cell( ...
-
堆栈的2D绘图(Stack of 2D plot)[2022-04-19]
这可以使用简单的plot命令完成 : from mpl_toolkits.mplot3d import axes3d import matplotlib.pyplot as plt import numpy as np NANGLES = 200 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') nvals = [0, 2, 4, 10, 20, 40, 100] for iy in range(len(nvals)): ... -
如何在Matlab中将2D矩阵序列存储到3D数组中?(How do i store sequence of 2D matrices into a 3D array in Matlab?)[2022-09-09]
好吧,第一个建议是尽量不要在matlab中使用变量i和j ,因为它们是保留的(看看这里和这里 )。 在它取决于您想要存储2D图像的尺寸之后: 如果要沿第一维存储图像,只需使用以下代码: a = dir('*.tif'); for ii = 1: numel(a) b = imread(a(ii).name); %read in the image b_threshold = graythresh(b ... -
Matlab中2D绘图的动画(Animation of 2D plot in Matlab)[2022-05-04]
如果我理解您的问题,您可以尝试以下方法:( 进一步修改最后评论后的代码) % Generate example data data=randi(10,1,100); data=[data;randi(10,1,100)+10] data=[data;randi(10,1,100)+20] data=[data;randi(10,1,100)+30] data=[data;randi(10,1,100)+40] t=1:101; h_fig=figure axes plot(data(:,1),t(1)) ... -
在matlab中绘制光分布曲线的2d和3d c平面(plot the 2d and 3d c-planes of a light distribution curve in matlab)[2023-05-19]
我没试过这个,但你可以使用pol2cart将你的极坐标转换为笛卡尔坐标,然后添加第三个维度并使用fill3渲染表面。 好的,我在这里拖延并实施它: % range of angles angles = 0:0.01:(2*pi); % light intensity example (insert values from table) r = 1 + sin(angles); % convert to cartesian coordinates [p1, p2] = pol2cart(angles, r ... -
如何在2D中绘制网格?(How can I plot a meshgrid in 2D?)[2023-07-31]
也许我在这里忽略了这一点,但是简单的plot(u,v,'b-x',u',v','b-x')什么问题? Maybe I'm missing the point here, but what's wrong with a simple plot(u,v,'b-x',u',v','b-x')? -
您可以使用interp2在相同的网格大小上查找中间值以进行可视化 step = 0.1; % granularity [xn,yn] = meshgrid(1:step:5); % define finer grid zn = interp2(x,y,z,xn,yn); % get new z values surf(xn,yn,zn); 请注意,您将使用默认线性插值方法获得与原始内核最接近的近似值,即interp2(x,y,z,xn,yn,'linear') 。 使用其他方法将导致使用更平滑的内核,但 ...