2016-09-23 204 views
-3

我已经写了使用synchronizedList()下面的代码:为什么synchronizedList不能正常工作

/* 
* To change this license header, choose License Headers in Project Properties. 
* To change this template file, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package collectionsdemo; 

import java.util.*; 

class ThreadTest implements Runnable 
{ 
    Thread t; 
    private int var; 

    public ThreadTest(int var) 
    { 
     t = new Thread(this); 
     this.var = var; 
     t.start(); 
    } 

    @Override 
    public void run() 
    { 
     System.out.println(var); 
    } 
} 

public class CollectionsDemo { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws InterruptedException { 
     List<ThreadTest> synlist = Collections.synchronizedList(new ArrayList<>()); 
     synlist.add(new ThreadTest(1)); 
     synlist.add(new ThreadTest(2)); 
     synlist.add(new ThreadTest(3)); 
     synlist.add(new ThreadTest(4)); 
     synlist.add(new ThreadTest(5)); 
     for (int i = 0; i < 5; i++) { 
      synlist.get(i).t.join(); 
     } 
     //System.out.println("Sunchronized list is :"+list); 
    } 

} 

现在,还是我在正确的顺序获得输出没有。他们每次都以不同的顺序进来。现在做什么?如何正确使用synchronizedList()方法?

+0

您预期的顺序是什么?为什么? –

+1

再次阅读'Collections.synchronizedList'规范。您会发现它与启动线程的顺序无关(但只提供线程安全操作) –

+0

线程的整个点是*并行执行*。你为什么期望他们按照任何特定的顺序运行? – shmosel

回答

0

由于您正在synchronizedList中添加threadtest对象,因此所有对象都将被添加到列表中,因为它们是列表,因为它是synchronizedList,所以它为您提供了额外的线程安全功能。

当你执行你的程序时,它会按照不同的顺序打印数字,因为这个数字正在被一个线程的treadtest类所触发,并且你不能通过这种方式控制线程的执行顺序。

但要确保添加的对象是自然顺序的,您可以在ThreadTest类中添加getVar()方法,并循环访问列表和打印var值,您可以看到它的顺序相同;

 class ThreadTest implements Runnable 
     { 
      Thread t; 
      private int var; 

      public ThreadTest(int var) 
      { 
       t = new Thread(this); 
       this.var = var; 
       t.start(); 
      } 

      @Override 
      public void run() 
      { 
       System.out.println(var); 
      } 

      public int getVar(){ 
       return var; 
      } 
} 


      public class CollectionsDemo { 
       /** 
       * @param args the command line arguments 
       */ 
       public static void main(String[] args) throws InterruptedException { 
        List<ThreadTest> synlist = Collections.synchronizedList(new ArrayList<>()); 
        synlist.add(new ThreadTest(1)); 
        synlist.add(new ThreadTest(2)); 
        synlist.add(new ThreadTest(3)); 
        synlist.add(new ThreadTest(4)); 
        synlist.add(new ThreadTest(5)); 
        for (int i = 0; i < 5; i++) { 
         synlist.get(i).t.join(); 
        } 

        for(ThreadTest test :synlist){ 
         System.out.println(test.getVar()); 
        } 
      //  System.out.println("Sunchronized list is :"+synlist); 
       } 

      }