关于synchronized的问题

marcovanbasten 2008-05-06 11:33:08
我有一个函数,供多线程来调用,其中有个参数是code。我想实现这样一个功能。
如果不同code的线程来调用这个函数,可以随便调用,没限制,但如果是同一个code的多个线程来调用,就需要同步一下,怎么用synchronized或其他方法实现呢?最好能有个例子,谢谢了啊!
...全文
133 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
加油馒头 2008-05-08
  • 打赏
  • 举报
回复
昨天刚刚看了一个与thread有关的ThreadLocal(一种线程的实现):线程内的局部变量,也就是水用过这个对象保存的变量值作用域只在当前的线程内与其他线程内的变量毫无关系,这就可以很好的解决你说的这个不同的线程中根据变量访问的函数(是否要进行同步)的问题.

今天你的问题后,大概想了下有种实现的方法.
1.当有线程进行访问时,你可以把当前的线程的CODE放入threadLocal中,好处是没个线程内的CODE值互不影响,因为threadloacl内的set(object o)方法的原理是根据thead.current做为map的关键字,CODE最为值,而且同一个线程在次保存值时不回重复.
2.当有线程要进行访问时,你可以通过threanlocal的get()方法(原理:根据当前的线程取出code),全部存入到一个map中
当要进行方法调用时,把map里的值全部取出来进行==判断,相等的则synchronized一下就可以了

mdog26 2008-05-07
  • 打赏
  • 举报
回复
饿
csrcom 2008-05-07
  • 打赏
  • 举报
回复

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class RWLock {

private String code;
private ReadWriteLock rwLock;

public RWLock(){
rwLock = new ReentrantReadWriteLock();
}

public String getCode() {
Lock lock = rwLock.readLock();
try{
lock.lock();
return code;
}finally{
lock.unlock();
}
}

public void setCode(String code) {
Lock lock = rwLock.writeLock();
try{
lock.lock();
this.code = code;
}finally{
lock.unlock();
}
}
}
marcovanbasten 2008-05-07
  • 打赏
  • 举报
回复
那我这样写就可以吗?
public static void f(String code)
{
// 不需要同步的内容。。。

synchronized(code)
{
// 需要同步执行的内容 。。。
}

// 不需要同步的内容。。。

}

然后这个函数供多线程来调用。
这样写真的可以吗?我总觉得就算是相同值的参数code进来,也会被同步的,还请高手解释。
chief_fu 2008-05-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yriio 的回复:]
code是对象么? 如果是就简单了

synchronized(code){
需要同步执行的内容
}
[/Quote]
就是这样了

回11楼,“虽然值一样,但不是同一个对象”,这并不违背lz的需求
forestking_xx 2008-05-06
  • 打赏
  • 举报
回复
怎么就算同一个code?
是不是code具有同样的值就是同一个code,值不同就不是同一个?
kekeemx 2008-05-06
  • 打赏
  • 举报
回复
好难明白楼主的意思啊.
就按照我的理解来说一下吧.
如果是同一个code的多个线程来调用,就需要同步一下
没错,就是在调用该方法的方法,对这个的方法进行同步应该差不多了
不过很奇怪啊,只读的话就从根本上不存在同步不同步的问题啊.
marcovanbasten 2008-05-06
  • 打赏
  • 举报
回复
另外9楼的,synchronized 是()里面的对象如果是同一个就同步,但我现在是由不同线程传进来的字符串对象,值是一样的,但对象未必是同一个吧?
marcovanbasten 2008-05-06
  • 打赏
  • 举报
回复
楼上的,我举的例子中的code就是一个字符串,也算一个对象吧。
比如现在同时启动了5个线程,其中有3个线程(设为线程1、2、3)中的code的内容是"a",还有1个(设为线程4)是"b",它们同时来调用f函数,我现在想要的效果就是,如果这时候线程1调用到了,那么2、3线程不能再调了,直到1调完了它们才能接着调用,但是线程4可以在同一时间调用f函数。
请问你的这个作法可以获得这个效果吗?
5楼这位兄弟的这个方法:synchronized f(final String code) 可以吗?
yriio 2008-05-06
  • 打赏
  • 举报
回复
synchronized 是()里面的对象是同一个的 就同步 不是同一个 那就么影响...

里面必须是一个对象.
yriio 2008-05-06
  • 打赏
  • 举报
回复
code是对象么? 如果是就简单了

synchronized(code){
需要同步执行的内容
}
w5325698 2008-05-06
  • 打赏
  • 举报
回复
调用thread里的lock()这个死锁方法撒,不就能保证一次只有一个线程能调用拉吗?
marcovanbasten 2008-05-06
  • 打赏
  • 举报
回复
5楼的这种作法,会不会无论code是否相同,都一律只允许一个线程执行函数里的内容吧?
是不是因为那个final,就可以满足我的要求了?
一步一个脚印 2008-05-06
  • 打赏
  • 举报
回复
synchronized f(final String code)
marcovanbasten 2008-05-06
  • 打赏
  • 举报
回复
不好意思,我可能说的不清楚。
举个例子,有个函数f(String code)
然后可能会有多个线程来调用这个函数,自然要把code传进来。如果有几个相同code的线程过来调用,那么要保证同一时间只有一个线程会执行函数f里的内容,如果有其他code的线程过来调用,则没有这个限制。。
3楼看来明白我的意思了,但办法不可取,因为实际情况中,code可能非常非常多,这种做法太占用内存。
2楼你的理解是正确的。
ahua3515 2008-05-06
  • 打赏
  • 举报
回复
思路:你的那个函数所在的那个类,不要设成单例。比如名字叫FunctionContainer
然后设置一个map,key=code,value=new FunctionContainer();
每一次当某个code来调用该函数的时候你判断map.contains(code)如果存在则取出该类,并执行。如果不存在,这new FunctionContainer();放入map中并调用它的对应的函数。这样就应该实现你的想法了吧

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧