大家好:
    我的程序中定义了ThreadClass1 ThreadClass2 两个类(从Thread继承)。
    有一个全局的数组A[10]
    ThreadClass1中会write A[]
    ThreadClass2中会Read  A[] 
    为了保证A[0]..A[9]是ThreadClass1在同一次写入的数据,
     该如何写?能提供例程吗?                                    谢谢!
 

解决方案 »

  1.   

    我也是新手 但是看了你的题目我有个想法 
    能不能在主类里面设置一个String a在ThreadClass1和ThreadClass2构造函数中传入
    当ThreadClass1要下数据的时候把a设置为"writing" 写完之后设置为"write ok!"
    然后ThreadClass2读取的时候做一个判断 如果a是"writing"的话就阻塞等待 直到a为"write ok!"希望我能抛砖引玉 有高手来给予指点
      

  2.   

    如果只有两个线程和一个全局变量的话,简单地使用synchronize就可以啦。
      

  3.   

    参考 notify() 和wait() 方法的用法 好象有个经典的生产者消费者的例子应该是处理这类问题的.
    给一段参考代码吧:public class WaitComm {
    public static void main(String[] args) {
    WFlagSend s = new WFlagSend();
    WFlagRec r = new WFlagRec(s);
    Thread st = new Thread(s);
    Thread rt = new Thread(r);
    rt.setDaemon(true);
    st.start();
    rt.start();
    try {
    st.join();
    while ( s.isValid ){
    Thread.sleep(100);
    }
    }catch(InterruptedException e){
    e.printStackTrace();
    }
    }
    }class WFlagSend implements Runnable {
     int theValue;
     boolean isValid;

    public void run() {
    for ( int i=0; i<5; i++){
    synchronized(this){
    while (isValid){
    try{
    this.wait();
    }catch(Exception e){e.printStackTrace();}
    }
    }
    theValue = (int)(Math.random()*256);
    System.out.println("sending " + theValue );
    synchronized(this){
    isValid = true;
    this.notify();
    }

    }
    }
    }class WFlagRec implements Runnable {
    private WFlagSend theSender;
    public WFlagRec(WFlagSend sender){
    theSender = sender;
    }
    public void run() {
    while ( true ) {
    synchronized(theSender) {
    while ( !theSender.isValid ){
    try{
    theSender.wait();
    }catch(Exception e){e.printStackTrace();}
    }

    }
    System.out.println("received " + theSender.theValue);
    synchronized(theSender) {
    theSender.isValid = false;
    theSender.notify();
    }
    }
    }
    }
      

  4.   

    我的程序和“caoyinghui1986 ”提供的很类似。
    “synchronized(theSender)” 有可能实现两个不同类的数据同步。我试试看。
      

  5.   

    你是想write一个 然后 read一个  反复这样吗?还是先全部write,所有的数write后,再read?
      

  6.   

    TO:jinglang
    基本上是前者。
    一个线程接收网络数据write A[0]..A[9]
    另一个线程在某个事件触发后(比如每5秒) read A[0]..A[9] 
    我主要担心读的A[]不是同一次写入的,如: A[0] A[1]是第8次写入的, A[2]..A[9]是第7次写入的
      

  7.   

    5楼给的代码很好但是应该给详细的讲一下
    另外就是WFlagSend 这个类似乎只能有一个实例在运行如果有就不能有效的保证对临界资源的同步访问了
      

  8.   


    class Test
    {
           public static void main(String[] args)
           {
                   final Arrays a = new Arrays();
                   Thread t1 = new Thread()
                   {
                           public void run()
                           {
                                   int j=1;
                                   while(true)
                                   {
                                           a.write(j++);
                                   }
                           }
                   };
                   Thread t2 = new Thread()
                   {
                           public void run()
                           {
                                   while(true)
                                   {
                                           a.read();
                                   }
                           }
                   };
                   t1.start();
                   t2.start();
           }
    }class Array
    {
           int n = 0;
           int[] num = new int[n];
           boolean b = false;
           synchronized void write(int j)
           {
                   int n = 0;
                   try
                   {
                           if (b)
                           {
                                   wait();
                           }
                   }
                   catch(Exception e)
                   {
                           System.out.println(e);
                   }
                   num[n++] = j;
                   System.out.println(Thread.currentThread().getName()+" "+num[n]);
                   b = true;
                   notify();
           }
           synchronized void read()
           {
                   try
                   {
                           if(!b)
                           {
                           wait();
                           }
                   }
                   catch(Exception e)
                   {
                           System.out.println(e);
                   }
                   System.out.println(Thread.currentThread().getName()+" "+num[n]);               b = false;
                   notify();
           }
    }
    写一个 读一个
      

  9.   

    嗯是synchronized修饰一下run方法然后定义一个boolean型的变量,用来控制线程的读取
      

  10.   


    public class Synchronized {
    static class Account{
    private double money=1000.0d;
    public void nonSynDeposit(double fFees){
    System.out.println("Account nonSynDeposit begin! money= "+this.money+"fFees= "+fFees);
    System.out.println("Account nonSynDeposit sleep begin!");
    try{
    Thread.sleep(300);

    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("Account nonSynDeposit end! money= "+this.money);
    }

    public void nonSynWithdraw(double fFees){
    System.out.println("Account nonSynWithdraw begin! money= "+this.money+" fFees= "+fFees);
    System.out.println("Account nonSynWithdraw sleep begin!");
    try{
    Thread.sleep(400);

    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("Account nonSynWithdraw sleep begin!");
    this.money=this.money-fFees;
    System.out.println("Account nonSynWithdraw end money= "+this.money+" fFees= "+fFees);
    }

    public synchronized void synDeposit(double fFees){
    System.out.println("Account synDeposit begin! money= "+this.money+" fFees= "+fFees);
    System.out.println("Account synDeposit sleep begin!");
    try{
    Thread.sleep(300);

    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("Account synDeposit begin!");
    this.money=this.money+fFees;
    System.out.println("Account synDepost end! money= "+this.money+" fFees= "+fFees);
    }

    public synchronized void synWithdraw(double fFees){
    System.out.println("Account synWithdraw begin! money= "+this.money+" fFees= "+fFees);
    System.out.println("Account synWithdraw sleep begin!");
    try{
    Thread.sleep(400);

    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("Account synWithdraw sleep end!");
    this.money=this.money-fFees;
    System.out.println("Account synWithdraw end! money= "+this.money+" fFees= "+fFees);
    }
    static class AccessThread extends Thread{
    private Account account=null;
    private String method="";

    public AccessThread(Account account,String method){
    this.method=method;
    this.account=account;
    }
    public void run(){
    if(method.equals("nonSynDeposit")){
    account.nonSynDeposit(500.0);
    }else if(method.equals("nonSynWithdraw")){
    account.nonSynWithdraw(200.0);
    }else if(method.equals("synDeposit")){
    account.synDeposit(500.0);
    }else if(method.equals("synWithdraw")){
    account.synWithdraw(200.0);
    }
    }

    }



    public static void main(String []args){
    Account account=new Account();
    System.out.println("使用非同步方法时:");
    Thread threadA=new AccessThread(account,"nonSynDeposit");
    Thread threadB=new AccessThread(account,"nonSynWithdraw");
    threadA.start();
    threadB.start();
    try{
    threadA.join();
    threadB.join();

    }catch(InterruptedException e){
    e.printStackTrace();
    }
    System.out.println("");
    account=new Account();
    System.out.println("使用同步方法时:");
     threadA=new AccessThread(account,"SynDeposit");
     threadB=new AccessThread(account,"SynWithdraw");
     threadA.start();
     threadB.start();
    } }}
      

  11.   

    我用Pipe的方式实现。参考:
    http://safari.oreilly.com/0137669658/ch02lev1sec6Using Pipes for Communication between Threads
    Sometimes, the communication pattern between threads is very simple. One thread, the so-called producer, generates a stream of bytes. Another thread, the so-called consumer, reads and processes that byte stream. If no bytes are available for reading, the consumer thread blocks. If the producer generates data much more quickly than the consumer can handle it, then the write operation of the producer thread blocks. Java has a convenient set of classes, PipedInputStream and PipedOutputStream, to implement this communication pattern. (There is another pair of classes, PipedReader and PipedWriter, if the producer thread generates a stream of Unicode characters instead of bytes.)The principal reason to use pipes is to keep each thread simple. The producer thread simply sends its results to a stream and forgets about them. The consumer simply reads the data from a stream, without having to care where it comes from. By using pipes, multiple threads can be connected with each other.Example 2-7 is a program that shows off piped streams. We have a producer thread that emits random numbers at random times, a filter thread that reads the input numbers and continuously computes the average of the data, and a consumer thread that prints out the answers. (You'll need to use Ctrl+C to stop this program.) Figure 2-10 shows the threads and the pipes that connect them. Unix users will recognize these pipe streams as the equivalent of pipes connecting processes in Unix.
    import java.io.*;public class PipeTest 
    { public static void main(String args[]) 
       { try 
          { /* set up pipes */ 
             PipedOutputStream pout1 = new PipedOutputStream(); 
             PipedInputStream pin1 = new PipedInputStream(pout1);         PipedOutputStream pout2 = new PipedOutputStream(); 
             PipedInputStream pin2 = new PipedInputStream(pout2);         /* construct threads */         Producer prod = new Producer(pout1); 
             Filter filt = new Filter(pin1, pout2); 
             Consumer cons = new Consumer(pin2);         /* start threads */         prod.start(); 
             filt.start(); 
             cons.start(); 
          } 
          catch (IOException e){} 
       } 
    }class Producer extends Thread 
    { public Producer(OutputStream os) 
       { out = new DataOutputStream(os); 
       }   public void run() 
       { for(;;) 
          { try 
             { double num = rand.nextDouble(); 
                out.writeDouble(num); 
                out.flush(); 
                sleep(Math.abs(rand.nextInt() % 1000)); 
             } 
             catch(Exception e) 
             { System.out.println("Error: " + e); 
             } 
          } 
       } 
       private DataOutputStream out; 
       private Random rand = new Random(); 
    }class Filter extends Thread 
    { public Filter(InputStream is, OutputStream os) 
       { in = new DataInputStream(is); 
          out = new DataOutputStream(os); 
       }   public void run() 
       { for (;;) 
          { try 
             { double x = in.readDouble(); 
                total += x; 
                count++; 
                if (count != 0) out.writeDouble(total / count); 
             } 
             catch(IOException e) 
             { System.out.println("Error: " + e); 
             } 
          } 
       }   private DataInputStream in; 
       private DataOutputStream out; 
       private double total = 0; 
       private int count = 0; 
    }class Consumer extends Thread 
    { public Consumer(InputStream is) 
       {   in = new DataInputStream(is); 
       }   public void run() 
       { for(;;) 
          { try 
             { double avg = in.readDouble(); 
                if (Math.abs(avg - old_avg) > 0.01) 
                { System.out.println("Current average is " + avg); 
                   old_avg = avg; 
                } 
             } 
             catch(IOException e) 
             { System.out.println("Error: " + e); 
             } 
          } 
       } 
       private double old_avg = 0; 
       private DataInputStream in; 
    }