传入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();

解决方案 »

  1.   

    没看懂你想干啥,但你应该知道:“String对象是不可修改的”。从代码肤浅的来看,对于 String s 来说,有两种结果:
    1、你想干的事情绝对不可能实现;
    2、你想干的事情绝对没有并发问题。
      

  2.   

    java.lang.String类中,没有变更里面字符的方法,所以,String是当做常量使用的。
    所以,线程里面对String的操作,按楼主的写法,貌似传不出来。
    如果楼主要共享String的内容,可以写成线程的静态变量;或者,使用StringBuffer对象。
      

  3.   

    这个变量只需存在Thread里不用回传
    所以我想是否在Thread里建个static变量就可以使用?
      

  4.   


    ◎ 总的来说,情况是:
    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"); // 超猪头做法
      

  5.   

    这个问题看起来像是互斥的问题你可以这么干,在线程里面,先运行s.wait();,用完s后运行s.notify();就像这样
    public void run()
    {
      s.wait();
      ...  
      s.notify();
    }
    这样就不会出现s被两个线程同时修改的情况了
      

  6.   

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

  7.   

    不好意思,原先说的方法是错的,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();
    }
    }
    }
    }
      

  8.   


    虽然你企图用synchronized解决并发问题,但LoopThread的几个实例准备怎么共享filter?如果是直接 static String filter 的话, 那么这个函数的参数和return就显得多余了,而且增加危险性。
      

  9.   


    这种做法是可以的;不过可以直接点,不创建新类,也可以这样了: 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");   
      }
    }
      

  10.   


    因为我会起15个Thread但希望这个lock是共用且可以新增所以可以改成以下这样?
        private static Object lock;        //互斥的工具
    其他都和你写的相同
      

  11.   


    意思是说,可能容易被误用,而导致脱离了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 去维护这种关键资源。