-1

我有这样的代码,

public int handle_refresh(Data mmsg) throws Exception {
        String custId = mmsg.getCustomerId();       
        CustomerThread t = custMap.get(mmsg.getCustomerId());
        if (t == null || !t.isAlive()) {
            t = (CustomerThread) context.getBean("custT");
            t.initThread(mmsg.getCustomerId(), mmsg.getCustomerId(), mmsg.getMessageBody());
            custSMap.put(mmsg.getCustomerId(), t);
            t.createBufferThread();
            t.start();
            t.initStreaming();
        }
        synchronized (t) {
            if (null != t) {
                ret = t.addSymbols(mmsg);
            }
        }
        return ret;
    }


                        }

这里 CustomerThread 在 custMap 中被检查,

映射 custMap=new CustomerThread();

如果 custMap 中有线程

1)然后阅读spring appilcation上下文并获取它。t = (CustomerThread) context.getBean("custT");

2) 在 initThread 方法中,为每个客户设置唯一的线程名称。 t.initThread(mmsg.getCustomerId(), mmsg.getCustomerId(), mmsg.getMessageBody());

3)然后将新创建的线程放入映射 custMap. custSMap.put(mmsg.getCustomerId(), t);

4) 然后在 createBufferThread 中将数据设置到缓存中..t.createBufferThread();

5)然后重新启动线程,然后从db中获取数据。 t.start();

6)设置数据库连接

如果 custMap 中没有线程

1)synchronized (t) .

2) 打电话t.addSymbols()方法。

我的问题是...

1)这里第一个 if 块只执行第一次,并且如果创建一次线程总是执行同步(t)?

我的意思是 if 块中的所有上述 1 到 6 个步骤只执行一次?

2)那么 synchronized (t) 做了什么?

4

2 回答 2

1

在我看来,这sychronized (t)是在保护addSymbols方法以使其成为线程安全的。t我假设对这个方法的调用是向线程中的某些数据结构添加符号。可能是该线程中的其他方法synchronized意味着它将锁定Thread实例。这就是sychronized (t)这里所做的。

但这是添加线程安全的一种极其丑陋的方式。该addSymbols(...)方法本身应该锁定在一个锁定对象上,或者,如果有必要,是一个synchronized方法。一个类应该负责它自己的锁定,而不需要调用者做某事。

关于您的代码的其他一些评论:

t = (CustomerThread) context.getBean("custT");

上面的代码似乎是从 Spring 中获取一个线程实例。这通常是一个单例,除非“custT”bean 是某种线程工厂。handle_refresh如果它不是工厂 bean,那么每次调用您的方法并重新初始化它时,您都将获得相同的线程对象。这很可能不是您想要的。

synchronized (t) {
    if (null != t) {
        ret = t.addSymbols(mmsg);
    }
}

如果t是,null那么该synchronized行将抛出 NPE。你不需要null里面的检查synchronized

CustomerThread t = custMap.get(mmsg.getCustomerId());

如果handle_refresh(...)从多个线程调用该方法,那么您需要确保该custMap方法也正确同步。

于 2012-09-10T12:28:57.243 回答
0

if 块应该只对每个客户 ID 执行一次。注意 if 块中的这行代码:

custSMap.put(mmsg.getCustomerId(), t);

它填充地图,因此下次使用该 customerId 进行搜索时,将找到它并执行同步块。

Synchronized 块将在互斥锁内调用 t 上的方法。

于 2012-09-10T12:27:55.077 回答