5

作者: 啊啊啊啊啊恩 | 来源:发表于2017-12-21 16:50 被阅读0次

[if !supportLists]1[endif]附录

[if !supportLists]1.1[endif]减少同步块范围

public boolean userHasAdminAccess(StringuserName) {

synchronized (attributesMap) {

String rights = attributesMap.get("users." + userName +".accessRights");

if (rights == null)

return false;

else

return (rights.indexOf("ADMIN") >= 0);

}

}

为创建串联的字符串“users.brian.accessRights”,编译器将创建一个临时的StringBuffer对象,调用StringBuffer.append三次,然后调用StringBuffer.toString,这意味着至少两个对象的创建和几个方法调用。接着,程序将调用HashMap.get检索该字符串,然后调用String.indexOf抽取想要的权限标识符。

public boolean userHasAdminAccess(StringuserName) {

String key = "users." + userName + ".accessRights";

String rights;

synchronized (attributesMap) {

rights = attributesMap.get(key);

}

return ((rights != null)

&& (rights.indexOf("ADMIN") >= 0));

}

需要注意StringBuffer是否为线程安全操作?

[if !supportLists]1.1[endif]减少锁粒度

public class AttributesStore {

private HashMap usersMap = new HashMap();

private HashMap servicesMap = new HashMap();

public synchronized void setUserInfo(String user, UserInfo userInfo) {

usersMap.put(user, userInfo);

}

public synchronized UserInfo getUserInfo(String user) {

return usersMap.get(user);

}

publicsynchronized void setServiceInfo(String service, ServiceInfo serviceInfo) {

servicesMap.put(service, serviceInfo);

}

public synchronized ServiceInfo getServiceInfo(String service) {

return servicesMap.get(service);

}

如果一个线程正在执行setUserInfo,不仅仅其它线程将被锁在setUserInfo和getUserInfo外面(这是我们希望的),而且这些线程也被锁在getServiceInfo和setServiceInfo外面。

public class AttributesStore {

private HashMap usersMap = new HashMap();

private HashMap servicesMap = new HashMap();

public void setUserInfo(String user, UserInfo userInfo) {

synchronized(usersMap) {

usersMap.put(user, userInfo);

}

}

public UserInfo getUserInfo(String user) {

synchronized(usersMap) {

return usersMap.get(user);

}

}

public void setServiceInfo(String service, ServiceInfo serviceInfo) {

synchronized(servicesMap) {

servicesMap.put(service, serviceInfo);

}

}

public ServiceInfo getServiceInfo(String service) {

synchronized(servicesMap) {

return servicesMap.get(service);

}

}

}

[if !supportLists]1.1[endif]信号量

如果多个线程需要访问数目很少的资源,可以使用信号量计数。将一个信号量初始化为可获得的资源数量。一旦某个线程获得了信号量,可获得的资源数减一。线程消耗完资源并释放该资源时,计数器就会加一。当信号量控制的所有资源都已被占用时,若有线程试图访问此信号量,则会进入阻塞状态,直到有可用资源被释放。

class Semaphore {

private int count;

public Semaphore(int n) {

this.count = n;

}

public synchronized void acquire() {

while(count == 0) {

try {

wait();

} catch (InterruptedException e) {

//keep trying

}

}

count--;

}

public synchronized void release() {

count++;

notify(); //alert a thread that's blocking on this semaphore

}

}

[if !supportLists]1.1[endif]什么是可见性

在一个单线程程序中,如果首先改变一个变量的值,再读取该变量的值的时候,所读取到的值就是上次写操作写入的值。也就是说前面操作的结果对后面的操作是肯定可见的。但是在多线程程序中,如果不使用一定的同步机制,就不能保证一个线程所写入的值对另外一个线程是可见的。造成这种情况的原因可能有下面几个:

[if !supportLists]l[endif]CPU内部的缓存:现在的CPU一般都拥有层次结构的几级缓存。CPU直接操作的是缓存中的数据,并在需要的时候把缓存中的数据与主存进行同步。因此在某些时刻,缓存中的数据与主存内的数据可能是不一致的。某个线程所执行的写入操作的新值可能当前还保存在CPU的缓存中,还没有被写回到主存中。这个时候,另外一个线程的读取操作读取的就还是主存中的旧值。

[if !supportLists]l[endif]CPU的指令执行顺序:在某些时候,CPU可能改变指令的执行顺序。这有可能导致一个线程过早的看到另外一个线程的写入操作完成之后的新值。

[if !supportLists]l[endif]编译器代码重排:出于性能优化的目的,编译器可能在编译的时候对生成的目标代码进行重新排列。

相关文章

  • 灵心儿组计分

    9.24 棉芯➕5➕5 晨萌➕5 乐乐➕5➕5➕5➕5 楠楠➕5➕5➕5➕5 水儿➕5➕5 七炫➕5➕5➕5➕5

  • 未闻花名口琴简谱

    1 4 5 5 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 4 4 4 4 1 1 1 4 5 5...

  • 5/5

    该地区最重要的科技增长毫无疑问是半导体产品。在新泽西州Bell实验室里,William曾是晶体管发明人之一,195...

  • 5/5

    我允许自己表达疲惫,允许自己懒懒前行,允许自己自然而然……感觉到放松,感觉到对自我的接纳,自己理解自己,直面自己,...

  • 5、5

    しょんぼり [寂しく]孤零零(地);[がっくり]垂气(成),无精打采(成) ¶~立っている/无精打采地站着 ¶彼は...

  • 5 .5

    今天去的晚了一点,然后男队那边早早就开始在训练了,但是女队现在还在慢悠悠的走,有十多分钟,这种学生投入性低,缺...

  • 5/5

    五一后第一天上课,虽然起晚了一点,不过语文课还是听上了。数学老师的课就是摸鱼,老师讲评了五一的卷子,真的超难!我原...

  • 托姆拉物语暴力火线技能树

    剑术:战吼5+5+10 射击:弱狙5+5+10 火线5+10 要领10 分身5+5+10 魔法:冲击波5+5+5+...

  • 密码

    1【5】1 云1 2【5】2 云2 3【5】3 云3 4【5】4 云4 5【5】5 云5 《2.0》 公告 6【5...

  • 20171109

    5:00-5:10 洗漱 V 5:10-5:40 晨间日记 V 5:40-5:50 反思昨天 V 5:50-5: ...

网友评论

      本文标题:5

      本文链接:https://www.haomeiwen.com/subject/ktbawxtx.html