建设门户网站人均ip1000需要多大数据库,南阳网站建设报价,大连做网站seo,wordpress配置环境如果多线程要并发的修改一个数据结构#xff0c;例如散列表#xff0c;那么很容易会破坏这个数据结构。一个线程可能要开始向表中插入一个新元素。假定在调整散列表各个桶之间的链接关系的过程中#xff0c;被剥夺了控制权。如果另一个线程也开始遍历同一个链表#xff0c;…  如果多线程要并发的修改一个数据结构例如散列表那么很容易会破坏这个数据结构。一个线程可能要开始向表中插入一个新元素。假定在调整散列表各个桶之间的链接关系的过程中被剥夺了控制权。如果另一个线程也开始遍历同一个链表可能使用无效的链接并造成混乱会抛出异常或者陷入死循环。   可以通过提供锁来保护共享数据结构但是选择线程安全的实现作为替代可能更容易些。上一篇讨论的阻塞队列就是线程安全的集合。接下来讨论java类库提供的另外一些线程安全的集合。   高效的映射表、集合和队列   java.util.concurrent包提供了映射表、有序集合和队列的高效实现ConcurrentHashMap、ConcurrentSkipListMap、ConcurrentSkipListSet和ConcurrentLinkedQueue。  java.util.concurrent.ConcurrentLinkedQueueEConcurrentLinkedQueueE() 构造一个可以被多线程安全访问的无边界非阻塞的队列。ConcurrentSkipListSetE(Comparateor? super E comp)    构造一个可以被多线程安全访问的有序集 java.util.concurrent.ConcurrentSkipListMapK,VConcurrentHashMapK,V()ConcurrentHashMapK,V(int initialCapacity)ConcurrentHashMapK,V(int initialCapacity,float loadFactor,int concurrencyLevel)  参数initialCapacity 集合的初始容量。默认值16        loadFactor      控制调整如果每一个桶的平均负载超过这个因子表的大小会被重新调整。默认值为0.75.      concurrencyLevel 并发写者结束 的估计数目。 ConcurrentSkipListMapK,VConcurrentSkipListSetK,VComparator? super k comp  构造一个可以被多线程安全访问的有序的映象表。第一个构造器要求键实现Comparable接口。 V putIfAbsent(K key,V value)  如果该键没有在映像表中出现则将给定的值同给定的键关联起来并返回null。否则返回与该键关键的现有值。 boolean remove(K key,V value)  如果给定的键与给定的值关联删除给定的键与值并返回真。否则返回false. boolean replace(K key,V oldValue,V newValue)  如果给定的键当前与oldvalue相关联用它与newValue关联。否则返回false 写数组的拷贝   CopyOnWriteArrayList和CopyOnWriteArraySet是线程安全的集合。其中所有的修改线程对底层数组进行复制。如果在集合上进行迭代的线程数超过修改线程数这样的安排是很有用的。当构建一个迭代器的时候它包含一个对当前数组的引用。如果数组后来被修改了迭代器仍然引用旧数组但是集合的数组已经被替换了。因为旧的迭代器拥有一致的视图访问无须任何同步开销。 Callable与Future Runnable封装了一个异步的任务可以把它想像成为一个没有参数和返回值的异步方法。Callable与Runnable类似但是有返回值。Callable接口是一个参数化的类型只有一个方法call。  public interface CallableV
{ V call() throws Exception;
}类型参数是返回值的类型。例如CallableInteger表示一个最终返回Integer对象的异步计算。   Future保存异步计算的结果。可以启动一个计算将Future对象交给某个线程然后忘掉它。Future对象的所有者在结果计算 好之后就可以获得它。   Future接口具有下面的方法  public interface FutureV
{V get() throws ...;V get(long timeout,TimeUnit unit) throws ...;void cancel(boolean mayInterrupt);boolean isCancelled();boolean isDone();    
}    第一个get方法的调用被阻塞直到计算完成。如果在计算完成之前第二个方法的调用超时抛出一个TimeoutException异常。如果运行该计算的线程被中断两个方法都将抛出InterruptedException。 如果计算完成那么get方法立即返回。   如果计算还在进行isDone方法返回false;如果完成了则么回true.   可以用cancel方法取消该计算。如果计算还没有开始它被取消且不再开始。如果计算处于运行中那么如果mayInterrupt参数为true它就被中断。   FutureTask包装器是一种非常便利的机制可以将Callable转换成Future转换成Future和Runnable它同时实现二者的接口。   以下这个例子与上一篇寻找包含指定关键字的文件的例子相似。然而现在我们仅仅计算匹配的文件数目。因此我们有了一个需要长时间运行的任务它产生一个数例一个CallableInteger的例子。  class MatchCouner implements CallableInteger
{public MatchCounter(Fille directory,String keyWord){...}public Integer call(){...} //返回匹配文件的数
}    然后我们利用MatchCounter创建一个FutureTask对象并用来启动一个线程。  FutureTaskInteger task new FutureTaskInteger(counter);
Thread tnew Thread(task);
t.start();最后打印结果   System.out.println(task.get() mathcing files.);当然对get的调用会发生阻塞直到有可获得的结果为止。   在call方法内部使用相同的递归机制。对于每一个子目录产生一个新的MatchCounter并为它启动一个线程。把FutureTask对象隐藏在ArrayListFutureInteger中。最后所有结果加起来  for(FutureInteger result:results)countresult.get()每一次对get的调用都会发生阻塞直到结果可获得为止。当然线程是并行运行的因此很可能在大致相同的时候所有的结果都可获得。完整代码如下   1 package test.Future;2 3 import java.io.File;4 import java.util.Scanner;5 import java.util.concurrent.ExecutionException;6 import java.util.concurrent.FutureTask;7 8 /**9  * Created by Administrator on 2017/11/23.
10  */
11 public class FutureTest {
12     public static void main(String[] args) {
13         Scanner in new Scanner(System.in);
14         System.out.print(输入查询路径);
15         String directoryin.nextLine();
16         System.out.print(输入关键字);
17         String keywordin.nextLine();
18 
19         MatchCounter counternew MatchCounter(new File(directory),keyword);
20         FutureTaskInteger tasknew FutureTask(counter);
21         Thread tnew Thread(task);
22         t.start();
23         try {
24             System.out.println(task.get() 匹配文件);
25         } catch (InterruptedException e) {
26             e.printStackTrace();
27         } catch (ExecutionException e) {
28             e.printStackTrace();
29         }
30 
31     }
32 }  View Code   1 package test.Future;2 3 import java.io.*;4 import java.util.ArrayList;5 import java.util.List;6 import java.util.Scanner;7 import java.util.concurrent.Callable;8 import java.util.concurrent.ExecutionException;9 import java.util.concurrent.Future;
10 import java.util.concurrent.FutureTask;
11 
12 /**
13  * 此任务对包含给定关键字的目录和子目录中的文件进行计数
14  */
15 public class MatchCounter implements CallableInteger {
16     private File directory;
17     private String keyword;
18     private int count;
19 
20     /**
21      * param directory 开始搜索目录
22      * param keyword   寻找关键字
23      */
24     public MatchCounter(File directory, String keyword) {
25         this.directory  directory;
26         this.keyword  keyword;
27     }
28 
29     Override
30     public Integer call() throws Exception {
31         count  0;
32         try {
33             File[] files  directory.listFiles();
34             if (files  null) {
35                 return count;
36             }
37             ListFutureInteger results  new ArrayList();
38             for (File file : files
39                     ) {
40                 if (file.isDirectory()) {
41                     MatchCounter counter  new MatchCounter(file, keyword);
42                     FutureTaskInteger task  new FutureTask(counter);
43                     results.add(task);
44                     Thread t  new Thread(task);
45                     t.start();
46                 } else {
47                     if (search(file)) {
48                         count;
49                     }
50                 }
51                 for (FutureInteger result : results) {
52                     try {
53                         count  result.get();
54                     } catch (ExecutionException e) {
55                         e.printStackTrace();
56                     }
57                 }
58             }
59         } catch (InterruptedException e) {
60         }
61         return count;
62     }
63 
64     /**
65      * 搜索一个给定关键字的文件
66      *
67      * param file
68      * return
69      */
70     public boolean search(File file) {
71         try{
72             try(Scanner in new Scanner(file,gbk)){
73                 boolean foundfalse;
74                 while (!foundin.hasNextLine()){
75                     String linein.nextLine();
76                     if (line.contains(keyword)){
77                         foundtrue;
78                         System.out.println(file.toString());
79                     }
80                 }
81                 return found;
82             }
83         }
84         catch (IOException e){
85             return false;
86         }
87     }
88 }  View Code  java.util.concurrent.CallableV     V call() 运行将产生结果的任务 V get() V get(long time,TimeUnit unit)  获取结果如果没有结果可用则阻塞直到得到结果超过指定的时间为止。如果不成功第二个方法会抛出TimeoutException异常。 boolean cancel(boolean mayInterrupt)  尝试取消这一任务的运行。如果任务已经开始并且mayInterrupt参数值为true它就会被中断如果成功执行取消操作返回true。 boolean isCancelled() 如果任务在完成前被取消了则返回true。boolean isDone() 如果任务结束无论是正常结束、中途取消或发生异常都返回true。 java.util.concurrent.FutureTaskV  FutureTask(CallableV task)FutureTask(Runnable task,V result) 构造一个既是FutureV又是Runnable的对象。    转载于:https://www.cnblogs.com/gousheng107/p/7885681.html