public class Data {
private int i; public Cache(int i) {
this.i = i;
} public void print() {
// System.out.println(i);
i++;
}
}
public class SetterThread extends Thread {
private int i; public void run() {
while (true) {
// try {
// sleep(5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
ThreadTest.data = new Cache(i++);
}
}
}
public class GetterThread extends Thread {
public void run() {
while (true) {
// try {
// sleep(5);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
if (ThreadTest.data != null) {
ThreadTest.data.print();
}
}
}
}public class ThreadTest { public static Data data; public static void main(String[] args) {
new GetterThread().start();
new SetterThread().start();
}}

解决方案 »

  1.   

    两个线程并发访问一个静态变量是线程不安全的。
    1. 你没有办法保证getter一定在setter之前执行
    2. 如果循环执行,你不能保证每次getter都会接着一次setter
      

  2.   

    先不要用教科书上的说线程安全的思路,我说说我的用意,我不需要getter一定在setter之前执行,也不需要每次getter都会接着一次setter
    我只需要这样做是不会出错,不会出异常,我想知道,在getter调用data.print的期间,如果setter去赋新的对象给data,会不会影响到getter或者我把getter改成这样:public class GetterThread extends Thread {
        public void run() {
            Data myData = null;
            while (true) {
                    myData = ThreadTest.data;
            }
        }
    }如果改成这样,会不会出问题,能不能保证myData一定能得到一个当时那一刻最新的对象,保证myData是引用了一个正确的对象
      

  3.   

    这个不是线程安全的,需要加锁
    public class Data {
        private int i;    public Cache(int i) {
            this.i = i;
        }    public void print() {
    //        System.out.println(i);
            i++;
        }
    }
    public class SetterThread extends Thread {
        private int i;    public void run() {
            while (true) {
    //            try {
    //                sleep(5);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
               synchronized(ThreadTest.data)
                {
                       ThreadTest.data = new Cache(i++);
                 }
            }
        }
    }
    public class GetterThread extends Thread {
        public void run() {
            while (true) {
    //            try {
    //                sleep(5);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
                synchronized(ThreadTest.data){
                if (ThreadTest.data != null) {
                    ThreadTest.data.print();
                }
                 }
            }
        }
    }public class ThreadTest {    public static Data data;    public static void main(String[] args) {
            new GetterThread().start();
            new SetterThread().start();
        }}
      

  4.   

    public class Data {
        private int i;    public Cache(int i) {
            this.i = i;
        }    public void print() {
    //        System.out.println(i);
            i++;
        }
    }Data类的构造函数叫Cache 这样也能编译通过么?
      

  5.   

    public class Mytest {    private Object lock = new Object();
        private int intNum;    public void execute() {        new Thread() {
                public void run() {
                    while (true) {
                        synchronized (lock) {
                            try {
                                lock.wait();
                            } catch (InterruptedException e1) {
                                e1.printStackTrace();
                            }
                        }
                        System.out.println("thread2 print num, intNum=" + intNum);
                    }            }
            }.start();
            
            new Thread() {
                public void run() {
                    while (true) {
                        intNum++;
                        System.out.println("thread1 add num, intNum=" + intNum);
                        synchronized (lock) {
                            lock.notify();
                        }
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }            }
            }.start();
            
        }
        
        public static void main(String[] argv){
            Mytest test=new Mytest();
            test.execute();
            
        }}