同步块不会阻止不同的对象 [英] syncronized block doens't block different objects

查看:95
本文介绍了同步块不会阻止不同的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在hashMap中插入(对于每一行):

i inserted in an hashMap (for each row) this:

rows.put(currentRow, new Object());
....

,并且在某些线程之后将调用此函数:

and after some threads will call this function:

   @Override
    public void run() {
        while (true) {
            increaseRow(new Random().nextInt(10));
            try {
                sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
      }

public  void increaseRow(Integer row) {
        synchronized (rows.get(row)) {
            for (int j = 0; j < column; j++) {
                matrix[row][j] += 1;
            }
            System.out.println("begin print");
            for (int i = 0; i < this.row; i++) {
                System.out.println();
                for (int j = 0; j < column; j++)
                    System.out.print(matrix[i][j]);
            }
            System.out.println();
            System.out.println("end print");
        }
   }

如果我启动1个线程,则可以,但是更多线程存在一些问题,例如:

if i start 1 thread, it works ok, but there are some problems with more threads, like:

begin print
00000
begin print
00
0000000000000000
00
000000000000000000000
00000000000
00000000000000
00000000000
00
000000000000
111111111111
000000000000
111000000000000
000000000000
111111111111
000000000000
111111111111
000000000000
0000000100000
end print

该地图只有10个键值,我正在同步对象值,所以我不明白这是怎么回事.

the map as only 10 key-value , i' m syncronizing on the object value, so i don't understand what's wrong.

提前谢谢.

推荐答案

要强制它仅对每行更新(不交错)打印开始打印",然后结束打印",则需要在行"上进行同步目的.

To force it to only print 'begin print' then 'end print' for each row update (not interleaved) you would need to synchronize on the 'rows' object.

虽然一次只能有1个线程可以写入rows.get(0)对象,但是您仍然可以锁定rows.get(0)和rows.get(1)以及rows.get(2)对象同时.这意味着您的输出可以连续包含开始打印"多次,后跟多条结束打印"行.

While only 1 thread at a time can write to the rows.get(0) object , you can still get a lock on rows.get(0) and rows.get(1) and rows.get(2) objects concurrently. This means your output can contain 'begin print' multiple times in a row followed by multiple 'end print' lines.

取决于您要在此处实现的目标-我只输出您要更新的行,因为您知道一次可以完成两个操作-仅同步所需的行.

Depending on what you're attempting to achieve here - I would simply output the row you're updating since you know that two can be done at once - synch only the row you wish.

public  void increaseRow(Integer row) {
    synchronized (rows.get(row)) {
        for (int j = 0; j < column; j++) {
            matrix[row][j] += 1;
        }
        System.out.println(String.format("begin update row %s", row));
        for (int i = 0; i < this.row; i++) {
            System.out.println();
            for (int j = 0; j < column; j++)
                System.out.print(String.format("row %s value %s",row,matrix[i][j]));
        }
        System.out.println();
        System.out.println("String.format("end update row %s", row)");
    }

}

或者如果您只是想让每个线程告诉您它更新了哪一行:

or if you just want each thread to tell you what row it updated:

    public  void increaseRow(Integer row) {
        synchronized (rows.get(row)) {
            for (int j = 0; j < column; j++) {
                matrix[row][j] += 1;
                System.out.print(String.format("row %s value %s",row,matrix[row][j]));
            }
        }
   }

这篇关于同步块不会阻止不同的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆