主题:深入理解同步(Threads: deep understanding of synchronizing)

我只是想在同步时更深入地了解内在机制。 我准备了3个例子。 我有问题涉及他们每个人。 所以这是第一个例子:


public class SyncExamples 
{

    SyncClass sync1, sync2;


    public void execute1()
    {
        sync1 = new SyncClass();
        sync1.process();
    }


    public void execute2()
    {
        sync2 = new SyncClass();
        sync2.process();
    }



    class SyncClass
    {

        public synchronized void process()
        {

        }
    }
}

SyncClass的方法process()是同步的。 但由于在SyncExamples类中创建了两个不同的SyncClass 对象 ,因此它们可以同时执行,而不是它们。 它们引用不同的对象,因此没有任何同步。 这样对吗?

第二个例子:


public class SyncExamples 
{

    SyncClass sync1 = new SyncClass();


    public void execute1()
    {       
        sync1.process();
    }


    public void execute2()
    {       
        sync1.process();
    }




    class SyncClass
    {

        public synchronized void process()
        {

        }
    }
}

所以在这个例子中他们引用了同一个对象。 所以这里我们有一个互斥量。 他们是同步的。 但让我们来看看对我来说最有趣的例子。


public class SyncExamples 
{

    SyncClass sync1 = new SyncClass();
    ReadWriteLock lock = new ReentrantReadWriteLock(); 


    public void execute1()
    {       
        lock.writeLock().lock();
        sync1.process();
        lock.writeLock().unlock();
    }


    public void execute2()
    {       
        execute1();
    }


    public void execute3()
    {       
        sync1.process();
    }


    public void execute4()
    {       
        execute1();
    }


    class SyncClass
    {

        public void process()
        {

        }
    }
}

execute2()启动execute1()。 execute1()锁定sync1.process()。 因此,execute4()必须等到execute1()解锁sync1.process()。 但是execute3()怎么样? 它没有引用execute1(),而是直接调用sync1.process()而没有任何锁定。 所以execute1()设置的锁对execute3()无效? 是对的吗? 锁只对那些引用execute1()的调用有效,因为这个方法定义了一个锁?

我在一天后添加了以下示例:


public class SyncExamples 
{

    List list = new ArrayList(); 


    public void processList1()
    {       
        synchronized(list)
        {
        }
    }


    public void processList2()
    {       
        synchronized(list)
        {
        }
    }


    public void execute3()
    {       
        processList1();
    }


    public void execute4()
    {       
        processList2();
    }
}

我想澄清最后一个例子。 现在我有一个我要同步的列表。 方法processList1()同步list ...方法processList2()也是如此。 但它们可以同时执行吗? 同步是否全局锁定列表(我的意思是来自其他方法的所有其他访问)或仅与特定方法结合使用? 我仍然不明白在这个例子中是否可以同时执行execute3()和execute4(),因为它们引用了不同的方法。 同步可防止第二次访问其块。 但是有几种方法想要访问列表并且他们使用自己的同步块。 因此,如果processList1()锁定列表,那么此列表是否会为processList2()锁定? 或者这个锁对processList2()无效,因为它是一个不同的方法?


I just want to get a deeper understanding of the inherent mechanisms while synchronizing. I prepared 3 examples. And I have questions that refer to each of them. So here is the first example:


public class SyncExamples 
{

    SyncClass sync1, sync2;


    public void execute1()
    {
        sync1 = new SyncClass();
        sync1.process();
    }


    public void execute2()
    {
        sync2 = new SyncClass();
        sync2.process();
    }



    class SyncClass
    {

        public synchronized void process()
        {

        }
    }
}

The method process() of SyncClass is synchronized. But due to the fact that in the class SyncExamples two different objects of SyncClass are created they both can be executed concurrently, can't they. They refer to different objects so there isn't any synchronization. Is it right?

The second example:


public class SyncExamples 
{

    SyncClass sync1 = new SyncClass();


    public void execute1()
    {       
        sync1.process();
    }


    public void execute2()
    {       
        sync1.process();
    }




    class SyncClass
    {

        public synchronized void process()
        {

        }
    }
}

So in this example they refer to the very same object. So here we have a mutex. They are synchronized. But let's come to the example most interesting for me.


public class SyncExamples 
{

    SyncClass sync1 = new SyncClass();
    ReadWriteLock lock = new ReentrantReadWriteLock(); 


    public void execute1()
    {       
        lock.writeLock().lock();
        sync1.process();
        lock.writeLock().unlock();
    }


    public void execute2()
    {       
        execute1();
    }


    public void execute3()
    {       
        sync1.process();
    }


    public void execute4()
    {       
        execute1();
    }


    class SyncClass
    {

        public void process()
        {

        }
    }
}

execute2() starts execute1(). execute1() locks sync1.process(). For this reason execute4() has to wait until sync1.process() is unlocked by execute1(). But what about execute3()? It does not refer to execute1() but calls directly sync1.process() without any lock. So the lock set by execute1() is not valid for execute3()? Is that right? The lock is only valid for those calls that refer to execute1() as this method defines a lock?

the following example I added one day later:


public class SyncExamples 
{

    List list = new ArrayList(); 


    public void processList1()
    {       
        synchronized(list)
        {
        }
    }


    public void processList2()
    {       
        synchronized(list)
        {
        }
    }


    public void execute3()
    {       
        processList1();
    }


    public void execute4()
    {       
        processList2();
    }
}

I would like to clarify this one last example. Now I have a list that I want to synchronize. Method processList1() synchronizes the list... method processList2() does it as well. But can they be executed concurrently? Does synchronized lock the list globally (I mean for all other accesses from other methods) or only in conjunction with the specific method? I still don't understand if execute3() and execute4() can be executed concurrently in this example as they refer to different methods. Synchronized prevents a second access to its block. But there are several methods that want to get access to the list and they use their own synchronized blocks. So if processList1() locks the list, is this list then locked for processList2()? Or is this lock not valid for processList2() as it is a different method?


原文:https://stackoverflow.com/questions/20668721
2023-07-17 19:07

满意答案

就像我在评论中发布的那样:我会启用剪辑self因为子视图backgroundView太大了。

另外:我会用

UIImageView *imgView = [[UImageView alloc] initWithImage:]
imgView.frame = CGRectMake(...)

也可以尝试机器人设置框架,因为Cell也可以自动设置backgroundView的框架


Like I posted in the comments: I would enable clipping on self because the subview backgroundView is too large.

In addition: I would use

UIImageView *imgView = [[UImageView alloc] initWithImage:]
imgView.frame = CGRectMake(...)

also try bot setting the frame, because maybe the Cell also sets the frame automatically of the backgroundView

相关问答

更多

为什么所有的背景消失在UITableViewCell选择?(Why do all backgrounds disappear on UITableViewCell select?)

正在发生的事情是,TableViewCell中的每个子视图都将接收setSelected和setHighlighted方法。 setSelected方法将删除背景颜色,但如果将其设置为所选状态,则将被更正。 例如,如果这些是在自定义单元格中添加为子视图的UILabels,则可以将其添加到TableViewCell实现代码的setSelected方法中: - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super s...

选择单元格时,UITableViewCell子视图消失(UITableViewCell subview disappears when cell is selected)

UITableViewCell在选择或突出显示单元格时更改所有子视图的背景颜色,您可以通过覆盖Tableview单元格的setSelected:animated和setHighlighted:animated来解决此问题setHighlighted:animated和重置视图背景颜色。 目标C: - (void)setSelected:(BOOL)selected animated:(BOOL)animated { UIColor *color = self.yourView.backgro...

在单元格的边界外面向UITableViewCell添加了UIImageView(Added UIImageView to UITableViewCell outside cell's bounds)

“然后这个图像显示在单元格的边界之外。” 你的视图不会在它的范围之外接受触摸,因此如果父视图没有,则子视图将不会接收到触摸 "This image is then displayed outside the bounds of the cell." your view will not receive touches outside it's bounds therefore the subview will not receive touches if it's parent does not

无法选择或访问超出滚动边界的uitableview单元格(不可见的单元格)(unable to select or access uitableview cell that is out of scroll bounds (cells that are not visible))

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"genericCell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; ...

如何使按钮透明的UITableViewCell的背景(How to make background of UITableViewCell with buttons transparent)

得到它了。 以为我会发布它,如果任何人都处于同样的困境: UIView *backView = [[UIView alloc] initWithFrame:CGRectZero]; backView.backgroundColor = [UIColor clearColor]; cell.backgroundView = backView; [backView release]; 现在看起来像这样: Got it. Thought I'd post it if anybody else is i...

UITableViewCell - 根据最后一个单元格的属性显示文本和背景图像(UITableViewCell - Text and background image are displayed based on last cell's attributes)

我认为问题在于您使用实例变量cellHeight来存储每行的单元格高度,并且在需要时不会更新。 您可以尝试使用(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath动态获取单元格高度- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)in...

iOS 7 UItableview单元格背景视图(iOS 7 UItableview cell background view)

尝试添加:cell.backgroundColor = [UIColor clearColor]; try adding : cell.backgroundColor = [UIColor clearColor];

保持UITableViewCell的背景视图忽略单元格边界(Keep UITableViewCell's background view from ignoring cell bounds)

就像我在评论中发布的那样:我会启用剪辑self因为子视图backgroundView太大了。 另外:我会用 UIImageView *imgView = [[UImageView alloc] initWithImage:] imgView.frame = CGRectMake(...) 也可以尝试机器人设置框架,因为Cell也可以自动设置backgroundView的框架 Like I posted in the comments: I would enable clipping on sel...

细胞背景视图不填充整个细胞(Cell background view not filling the whole cell)

试试这个代码。 它对我有用。 UIImageView * ac= [[UIImageView alloc] init]; ac.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"image.png"]]; cell.backgroundView =ac; cell.backgroundColor = [UIColor clearColor]; Try this code. it worked for me...

阻止单元格被拖出UITableView边界(Stop cell from being dragged out of UITableView bounds)

你可以像下面这样做.. [yourtableview setBounces:NO]; 让我知道它的工作与否!!!! 快乐的编码!!! you can do this like below.. [yourtableview setBounces:NO]; let me know it is working or not!!!! Happy Coding!!!

相关文章

更多

深入理解Android:卷2.pdf电子书下载

深入理解ANDROID 卷2 PDF的内容摘要:内容简介发售日期: 2012年8月20日 《深入理解A ...

深入理解Magento -前言

深入理解Magento 作者:Alan Storm 翻译:Hailong Zhang 前言 我从2 ...

深入理解Hadoop集群和网络 PDF

Hadoop主要的任务部署分为3个部分,分别是:Client机器,主节点和从节点。主节点主要负责Had ...

深入理解搜索-精确匹配搜索

查出在某个域中,含有某个词的指定文档数,要用到的方法是TermQuery,Query query = ...

Storm Topology的并发度

Understanding the parallelism of a Storm topology h ...

微信公共服务平台开发(.Net 的实现)12-------网页授权(上 :更加深入理解OAuth2.0 )

我们首先来认识一下OAuth协议吧,这个东西很早就听说过,总觉得离我很远(我的项目用不到这些),但是最 ...

原来炒股可以这样理解

草+古=炒股 ~~ 苦啊

Storm-源码分析-Topology Submit-Executor-mk-threads

对于executor thread是整个storm最为核心的代码, 因为在这个thread里面真正完成 ...

请问何为“同步流程”

请问何为“同步流程”

数据同步工具 DataX 的使用

架构设计 特点: 支持sql-server / oracle / mysql 等jdbc支持的数 ...

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本