线程定时操作

来源:互联网 发布:淘宝佣金是什么意思 编辑:程序博客网 时间:2024/06/04 18:17

题目需求:

声明一个共享数组,起两个线程,两个线程分别隔一段时间(可以写一个随机数),给数组中添加数据,每一个线程为数组添加3个数据即可。

思路:

方法一:

1、先创建一个Data类,实现Runnable接口,该类需有一个带参数的构造函数,传入共享数组,还需要有一个静态的index成员,给遍历数组赋值。

2、覆盖run方法,run方法中的代码需同步,隔一段时间用sleep()方法。这里需注意,用同步函数的时候,要保证在创建线程的时候只创建一个Data对象,因为同步函数的锁默认是当前对象,如果创建两个对象,就不能保证同步,而用同步代码块,用共享数组为锁,在创建线程的时候,可以创建两个匿名对象。

3、直接在main函数中创建两个线程运行即可,注意,数组最好在同步运行的时候打印,别直接主在main函数中,因为是多线程,若是将打印数组放在主线程中,没等添加数据的线程执行完,主线程就执行完了,所以会打印空数组,当然如果用join()方法控制两个添加数据的线程执行完,再执行主线程,也是可行的。

方法二:

1、创建一个Data2类,实现Runnable接口,该类需有一个带参数的构造函数,传入共享数组和ScheduledExecutorService对象。

2、覆盖run方法,该run方法不需要同步,因为JDK1.5新特性线程池内部保证了线程的安全同步问题,但是要注意,在数据添加完后,需关闭线程池,不然线程池会处于一直处理等待状态。线程的延时也用sleep方法,没有用scheduleAtFixedRate方法,是因为该方法总是以一个线程执行代码(至于怎么控制让线程池中的每个线程能按照延时,定时的规则去执行,我没找到实现方法......)

3、在主函数中创建一个List集合,用Executors.newScheduledExecutorService得到一个ExecutoService对象scheduler,然后在循环体中调用execute方法。

代码实现:

import java.util.ArrayList;import java.util.List;import java.util.Random;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;/** * 题目:声明一个共享数组,起两个线程,两个线程分别隔一段时间(可以写一个随机数),给数组中添加数据,每一个线程为数组添加3个数据即可。 * @author Administrator *///方法一:普通数组与传统多线程实现数据类class Data implements Runnable{private int[] arr;public static int index=0;Data(){}Data(int[] arr){this.arr = arr;}public void run (){synchronized(arr){//这地方不能直接在run上用同步函数,因为两个线程要new两次对象,同步函数默认的锁是this,所以不能保证两个线程的同步。//而同步代码块用arr将锁保持一致了,所以可以保证两个线程的同步。for(int i =0; i<3; i++){int data = new Random().nextInt(1000) % 100;arr[index] = data;index++;System.out.println(Thread.currentThread().getName()+":"+index+"添加了:"+data);try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}printArr(arr);}}//打印数组public static void printArr(int[] arr){if(Data.index == 6){System.out.print("[");for(int j = 0; j<5; j++){System.out.print(arr[j]+",");}System.out.println(arr[5]+"]");}}}//方法二:集合与JDK1.5线程池实现数据类class Data2 implements Runnable{private List<Integer> arrayList;private ScheduledExecutorService scheduler;Data2(){}Data2(List<Integer> arrayList,ScheduledExecutorService scheduler){this.arrayList = arrayList;this.scheduler = scheduler;}public void run(){synchronized(arrayList){int data = new Random().nextInt(1000) % 100;arrayList.add(data);System.out.println(Thread.currentThread().getName()+"向数组中添加了: "+data);try {Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(arrayList.size() == 6){scheduler.shutdownNow();System.out.println(arrayList);}}}}public class Test11 {public static void main(String[] args) throws Exception {// 方法二:final List<Integer> arrayList = new ArrayList<Integer>();//创建有两个线程的线程池,每隔3秒,分别向arrayList中添加100以内的随机数据final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);Data2 d2 = new Data2(arrayList,scheduler);for(int i = 0; i<6; i++){scheduler.execute(d2);//schedule的延时只是一次性的,但是为for循环了,为什么还是一次性的?}//方法一int[] arr = new int[6];new Thread(new Data(arr)).start();new Thread(new Data(arr)).start();}}


 

0 0
原创粉丝点击