stringbuffer和thread.join对线程控制的问题以及线程协作的问题

 1.关于StringBuffer线程安全的问题,如何理解?它的线程安全是控制到什么程度的?
下面的这段代码,输出什么?
public class StringBufferTest {
    private static StringBuffer sb = new StringBuffer();
    public static void main(String[] args) throws Exception {
        Thread t0  = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100;i ++) {
                    sb.append(i+" ");
                }
            }
        };

        Thread t1 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100;i ++) {
                    char c = (char)('a' + i);
                    sb.append(c+" ");
                }
            }
        };

        t0.start();
        t1.start();

        t0.join();//持有join的线程,会在该线程执行完毕后才能继续往下执行
        t1.join();

        System.out.println(sb);
    }
}
  答案:实际的结果是数字和字符打串了
 
2.如果我想首先打印线程1所有的数字,再打印线程2所有的所有字符,如何改这个代码
 
  Java Thread中, join() 方法主要是让调用改方法的thread完成run方法里面的东西后, 在执行join()方法后面的代码。
 
     所以应该为(两个线程顺序执行):
    
  t0.start();
    t0.join();
 
  t1.start();
      t1.join(); 
 
  如果为并发执行:
       在原来的代码的run(){
      synchronized(sb){
        for()
      }
  } 
        
 
3.如果我想首先打印线程1的一个数字,再打印线程2的一个字符,依次交替打印,如何改这个代码(线程协作)
   
 public class StringBufferTest {
    private static StringBuffer sb = new StringBuffer();
    private static boolean thread1Run =true;
    private static boolean thread2Run = false;
    public static void main(String[] args) throws Exception {
        Thread t0  = new Thread() {
            @Override
            public void run() {

                    for (int i =0 ; i< 100; i++) {
                           synchronized (sb){
                               while (!thread1Run) {
                                   try {
                                       sb.wait();
                                   } catch (InterruptedException e) {
                                       e.printStackTrace();
                                   }
                               }
                                sb.append(i + " ");
                               thread1Run = false;
                                thread2Run = true;
                                sb.notify();
                            }
                    }


            }
        };

        Thread t1 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    synchronized (sb) {
                        while (!thread2Run) {
                            try {
                                sb.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                        char c = (char)('a' + i);
                        sb.append(c + " ");
                        thread1Run = true;
                        thread2Run = false;
                        sb.notify();
                    }
                }
            }
        };

        t0.start();
        t1.start();

        t0.join();
        t1.join();

        System.out.println(sb);
    }
}
 
总结:
 我们说StringBuffer是线程安全的,不是说它是完全线程安全,即对StringBuffer的任何操作都不需要关心线程安全问题
而是它是部分线程安全,它的线程安全性体现在,调用append的操作时是安全的,因为这个方法加锁了
 所以,在两个线程里面同时分别执行sb.append("12345678"),sb.append("abcdef")
不会出现打串的情况
posted @ 2015-10-12 14:24  我在途中  阅读(218)  评论(0编辑  收藏  举报