首页 \ 问答 \ 在递归块挂起中使用CountDownLatch和Object.wait(Using CountDownLatch & Object.wait inside recursive block hangs)

在递归块挂起中使用CountDownLatch和Object.wait(Using CountDownLatch & Object.wait inside recursive block hangs)

问题:在尝试以分阶段方式检索递归块内的值时,执行会挂起。

描述: CountDownLatchObject.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 a CountDownLatch didn't take effect? Need someone's help in understanding what exactly is happening in this program.


原文:https://stackoverflow.com/questions/29066020
更新时间:2024-02-03 16:02

最满意答案

正如您所暗示的,对您的问题最有用的功能是: 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: enter image description here


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: enter image description here


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 ...
  • 如果您实际查看plot 文档 ,您会看到如果您将矩阵传递给它,它会将每列绘制为相同轴上的单独绘图对象。 因此,您可以简单地将数据的转置传递给plot 。 % Example data A = magic(10); % Create a plot for each row hplot = plot(A.'); 这将使用下一个绘图颜色绘制每个信号。 如果要确保拥有所有不同的颜色,可以使用颜色图(例如parula )为每个绘图显式设置不同的颜色。 set(hplot, {'Color'}, num2cell( ...
  • 这可以使用简单的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中使用变量i和j ,因为它们是保留的(看看这里和这里 )。 在它取决于您想要存储2D图像的尺寸之后: 如果要沿第一维存储图像,只需使用以下代码: a = dir('*.tif'); for ii = 1: numel(a) b = imread(a(ii).name); %read in the image b_threshold = graythresh(b ...
  • 如果我理解您的问题,您可以尝试以下方法:( 进一步修改最后评论后的代码) % 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)) ...
  • 我没试过这个,但你可以使用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 ...
  • 也许我在这里忽略了这一点,但是简单的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') 。 使用其他方法将导致使用更平滑的内核,但 ...

相关文章

更多

最新问答

更多
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • 电脑高中毕业学习去哪里培训
  • 电脑系统专业就业状况如何啊?
  • IEnumerable linq表达式(IEnumerable linq expressions)
  • 如何在Spring测试中连接依赖关系(How to wire dependencies in Spring tests)
  • Solr可以在没有Lucene的情况下运行吗?(Can Solr run without Lucene?)
  • 如何保证Task在当前线程上同步运行?(How to guarantee that a Task runs synchronously on the current thread?)
  • 在保持每列的类的同时向数据框添加行(Adding row to data frame while maintaining the class of each column)
  • 的?(The ? marks in emacs/haskell and ghc mode)
  • 一个线程可以调用SuspendThread传递自己的线程ID吗?(Can a thread call SuspendThread passing its own thread ID?)
  • 延迟socket.io响应,并“警告 - websocket连接无效”(Delayed socket.io response, and “warn - websocket connection invalid”)
  • 悬停时的图像转换(Image transition on hover)
  • IIS 7.5仅显示homecontroller(IIS 7.5 only shows homecontroller)
  • 没有JavaScript的复选框“关闭”值(Checkbox 'off' value without JavaScript)
  • java分布式框架有哪些
  • Python:填写表单并点击按钮确认[关闭](Python: fill out a form and confirm with a button click [closed])
  • PHP将文件链接到根文件目录(PHP Linking Files to Root File Directory)
  • 我如何删除ListView中的项目?(How I can remove a item in my ListView?)
  • 您是否必须为TFS(云)中的每个BUG创建一个TASK以跟踪时间?(Do you have to create a TASK for every BUG in TFS (Cloud) to track time?)
  • typoscript TMENU ATagParams小写(typoscript TMENU ATagParams lowercase)
  • 武陟会计培训类的学校哪个好点?
  • 从链接中删除文本修饰(Remove text decoration from links)