关于不同Thread中判断String是否存在

cscxxx 2012-02-03 09:30:09
传入Thread的都是ArrayList除了最后一个s是String
在每个Thread进行处理时都需要s来进行判断而且都会在s里附加文本
我的想法是用以下的方法是不是可行
但有一个问题是传入时s是""会不会同样二个进程同时抓到""那就会有问题
该如何避免这种问题?


String s="";
LoopThread lt01=new LoopThread(al1,al2,al3,al4,al5,al6,al7,al8,al9,al10,bomal2,al11,s );
lt01.start();
LoopThread lt02=new LoopThread(al2,al3,al4,al5,al6,al7,al8,al9,al10,al1,bomal2,al11,s );
lt02.start();
LoopThread lt03=new LoopThread(al3,al4,al5,al6,al7,al8,al9,al10,al1,al2,bomal2,al11,s );
lt03.start();
LoopThread lt04=new LoopThread(al4,al5,al6,al7,al8,al9,al10,al1,al2,al3,bomal2,al11,s );
lt04.start();
LoopThread lt05=new LoopThread(al5,al6,al7,al8,al9,al10,al1,al2,al3,al4,bomal2,al11,s );
lt05.start();
LoopThread lt06=new LoopThread(al6,al7,al8,al9,al10,al1,al2,al3,al4,al5,bomal2,al11,s );
lt06.start();
LoopThread lt07=new LoopThread(al7,al8,al9,al10,al1,al2,al3,al4,al5,al6,bomal2,al11,s );
lt07.start();
LoopThread lt08=new LoopThread(al8,al9,al10,al1,al2,al3,al4,al5,al6,al7,bomal2,al11,s );
lt08.start();
LoopThread lt09=new LoopThread(al9,al10,al1,al2,al3,al4,al5,al6,al7,al8,bomal2,al11,s );
lt09.start();
LoopThread lt10=new LoopThread(al10,al1,al2,al3,al4,al5,al6,al7,al8,al9,bomal2,al11,s );
lt10.start();
...全文
205 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
MiceRice 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cscxxx 的回复:]
我在该Tread里加一个方法如下是否可以?
public synchronized static String sappend(String filter,String s1,String s2){
filter=filter+s1+"$"+s2+";";
return filter;
}
[/Quote]

虽然你企图用synchronized解决并发问题,但LoopThread的几个实例准备怎么共享filter?

如果是直接 static String filter 的话, 那么这个函数的参数和return就显得多余了,而且增加危险性。



周靖峰 2012-02-03
  • 打赏
  • 举报
回复
不好意思,原先说的方法是错的,wait()和notify()是用于同步的,不是用于互斥的

还是用synchronized方法好了


public class Test
{
public static void main(String[] args)
{
StringBuilder s = new StringBuilder();
Object lock = new Object();
for (int i = 0; i < 10; i++)
{
new TestThread(i, s, lock).start();
}
}
}

class TestThread extends Thread
{
private int i; //线程编号
private StringBuilder s; //要处理的字符串
private Object lock; //互斥的工具

public TestThread(int i, StringBuilder s, Object lock)
{
this.i = i;
this.s = s;
this.lock = lock;
}

public void run()
{
while (true)
{
synchronized (lock)
{
s.append(i); //将自己的编号添加到字符串中
System.out.println(s); //打印这个字符串被哪些线程调用过
}

try
{
Thread.sleep(1000); //这里停一秒为了便于观察结果
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
cscxxx 2012-02-03
  • 打赏
  • 举报
回复
我在该Tread里加一个方法如下是否可以?
public synchronized static String sappend(String filter,String s1,String s2){
filter=filter+s1+"$"+s2+";";
return filter;
}
周靖峰 2012-02-03
  • 打赏
  • 举报
回复
这个问题看起来像是互斥的问题

你可以这么干,在线程里面,先运行s.wait();,用完s后运行s.notify();

就像这样


public void run()
{
s.wait();
...
s.notify();
}


这样就不会出现s被两个线程同时修改的情况了
MiceRice 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 cscxxx 的回复:]
这个变量只需存在Thread里不用回传
所以我想是否在Thread里建个static变量就可以使用?
[/Quote]

◎ 总的来说,情况是:
lt01 = new LoopThread(al1,al2,al3,al4,al5,al6,al7,al8,al9,al10,bomal2,al11,s);
lt02 = new LoopThread(al2,al3,al4,al5,al6,al7,al8,al9,al10,al1,bomal2,al11,s);

你在lt01里面,无论对s做什么事情,lt02也不知道(当然,那种用反射去直接操数据结构的除外)。
因为lt01中s形参,跟lt02中s形参,就是毫无关系的两个变量,虽然它们在刚进入函数的时候指向同一个String实例。


◎ 所以我想是否在Thread里建个static变量就可以使用?
可以,LoopThread 里面有个static变量的话,所有实例都引用一个变量了。但将面临资源并发访问的问题。

建议这样:
1、写一个类,比如名叫:SharedString,代替你原来的String参数;
2、SharedString中维护一个private 的 StringBuffer;
3、SharedString根据你LoopThread的操作需要,提供一组函数,并全部加上 synchronized;
4、严格注意函数必须是自完备的,也不要出现LoopThread代码中把一个函数的返回结果传给另一个函数,这就破坏了synchronized能保护的边界,比如:
SharedString ss = new SharedString();
ss.set(ss.get() + "asdf"); // 超猪头做法

cscxxx 2012-02-03
  • 打赏
  • 举报
回复
这个变量只需存在Thread里不用回传
所以我想是否在Thread里建个static变量就可以使用?
冰思雨 2012-02-03
  • 打赏
  • 举报
回复
java.lang.String类中,没有变更里面字符的方法,所以,String是当做常量使用的。
所以,线程里面对String的操作,按楼主的写法,貌似传不出来。
如果楼主要共享String的内容,可以写成线程的静态变量;或者,使用StringBuffer对象。
MiceRice 2012-02-03
  • 打赏
  • 举报
回复
没看懂你想干啥,但你应该知道:“String对象是不可修改的”。

从代码肤浅的来看,对于 String s 来说,有两种结果:
1、你想干的事情绝对不可能实现;
2、你想干的事情绝对没有并发问题。
ilovefzq 2012-02-03
  • 打赏
  • 举报
回复
高手的问题,只能是高手回答了
周靖峰 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 cscxxx 的回复:]

引用 7 楼 nbda1121440 的回复:

不好意思,原先说的方法是错的,wait()和notify()是用于同步的,不是用于互斥的

还是用synchronized方法好了

Java code

public class Test
{
public static void main(String[] args)
{
StringBuilder s = new S……
[/Quote]

这个是可以的,只要你的15个线程的互斥工具都是同一个对象就行了
MiceRice 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 cscxxx 的回复:]
请教危险性指的是什么?
[/Quote]

意思是说,可能容易被误用,而导致脱离了Synchronized的控制范围,比如:


LoopThread {
private static String a;
public void run() {
a = sappend(a, s1, s2); // 这句话就已经脱离了synchronized控制范围,有并发问题
}

public synchronized static String sappend(String filter,String s1,String s2){
filter=filter+s1+"$"+s2+";";
return filter;
}
}


一般来说,从设计严谨性出发,应该消除所有可能被误用的口子;尤其是如果这个程序可能是协作开发的情况下,未必每一个人都能理解你的原始设计意图;这也是为什么我建议专门定义 SharedString 去维护这种关键资源。
cscxxx 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ldh911 的回复:]

引用 6 楼 cscxxx 的回复:
我在该Tread里加一个方法如下是否可以?
public synchronized static String sappend(String filter,String s1,String s2){
filter=filter+s1+"$"+s2+";";
return filter;
}


虽然你企图用synchronized解决并发问题……
[/Quote]

请教危险性指的是什么?
cscxxx 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 nbda1121440 的回复:]

不好意思,原先说的方法是错的,wait()和notify()是用于同步的,不是用于互斥的

还是用synchronized方法好了

Java code

public class Test
{
public static void main(String[] args)
{
StringBuilder s = new StringBuilder();
……
[/Quote]

因为我会起15个Thread但希望这个lock是共用且可以新增所以可以改成以下这样?
private static Object lock; //互斥的工具
其他都和你写的相同
lxbccsu 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ldh911 的回复:]
引用 3 楼 cscxxx 的回复:
这个变量只需存在Thread里不用回传
所以我想是否在Thread里建个static变量就可以使用?


◎ 总的来说,情况是:
lt01 = new LoopThread(al1,al2,al3,al4,al5,al6,al7,al8,al9,al10,bomal2,al11,s);
lt02 = new LoopThread(al2,al3,……
[/Quote]

这种做法是可以的;

不过可以直接点,不创建新类,也可以这样了: set(get() + "asdf"); // 超猪头做法
传递一个ArrayList<String> aList代替s;
再在LoopThread中加个方法:

ArrayList<String> aList = new ArrayList<String>(1)
aList.add(s);
new LoopThread(...,aList);

...

LoopThread中:
ArrayList<String> aList = 传递来的aList;
public void changeValue(){
synchronized(aList){
aList.set(0, aList.get(0) + "asdf");
}
}


62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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