初识JAVA---并发API、线程池、Timer(9)

java.util.concurrent包及其子包提供了一系列工具,更好,更方便得使用线程

下面介绍几个实用的类   单变量,集合,Timer,线程池

 

原子变量

      线程在执行任务的时候,需要些同步控制,但自己的可能有问题,在java.util.concurrent.atomic包中,提供了一AtomicInteger类,原子类,这个类在线程访问的时候是安全的,不会在执行到一般 别的线程参合进来执行。

 

下面这个例子中,我们先创建了1000个线程

每个线程对i++   同时对比原子整数的++

结果表明  原子变量是线程安全的 

结果:

999 false
1000 true

import java.util.concurrent.atomic.AtomicInteger;
class AtomicIntegerDemo
{
	static int n=0;
	static AtomicInteger cnt=new AtomicInteger(0);
	public static void main(String[] args)
	{
		final int NUM=1000;
		Thread[] threads=new Thread[NUM];
		for(int i=0;i<NUM;i++) {
			threads[i]=new Thread() {
				public void run() {
					n++;
					cnt.getAndIncrement();//Add 1 在线程中+1  线程安全
				}
			};
		}
		for(int i=0;i<NUM;i++)threads[i].start();
		try {Thread.sleep(3000);}
		catch(InterruptedException ex) {}
		System.out.printf("%d %b\n",n,n==NUM);
		System.out.printf("%d %b\n",cnt.get(),cnt.get()==NUM);
	}

}

    1.5以前 ArrayList HashMap不是线程安全的   

    vector 以及 Hashtable是线程安全的

    下面这些都是线程安全的

   Collections.synchronizedArrayList(list)

    java.util.concurrent中   CopyOnWriteArrayList  CopyOnWriteArraySet  是线程安全的类

   ConcurrentHashMap  pubIfAbsent()  remove()  replace()   

    ArrayBlockingQueue  可以实现生产者消费者模型  是应用put() take()

 

下面看一些线程安全的方法写的例子   结果  从结果上来看 彼此的叠加是互不干扰的

Prodece 0.
Consume 0.
Prodece 1.
Consume 1.
Prodece 2.
Prodece 3.
Consume 2.
Prodece 4.
Prodece 5.
Consume 3.
Consume 4.
Consume 5.
 

import java.util.concurrent.*;
class Producer implements Runnable{
	private BlockingQueue<Integer>queue;
	public Producer(BlockingQueue<Integer>queue) {
		this.queue=queue;
	}
	public void run() {
		for(int i=0;i<=5;i++) {
			try {
				Thread.sleep((int)(Math.random()*10));
				queue.put(i);//用put  take  的时候就不用底层去写  wati  notify等方法
				System.out.println("Prodece "+i+".");
			}catch(InterruptedException ex) {}
		}
	}
}
class Consumer implements Runnable{
	private BlockingQueue<Integer>queue;
	public Consumer(BlockingQueue<Integer>queue) {
		this.queue=queue;
	}
	public void run() {
		for(int i=0;i<=5;i++) {
			try {
				Thread.sleep((int)(Math.random()*20));
				Integer product =queue.take();
				System.out.println("Consume "+product+".");
			}catch(InterruptedException ex) {}
		}
	}
}

class BlockingQueueDemo{
	public static void main(String[] args) {
		BlockingQueue<Integer>queue=new ArrayBlockingQueue<>(3);
	new Thread(new Producer(queue)).start();
	new Thread(new Consumer(queue)).start();
	}
}

 

线程池

线程池可以简单理解为 同时开好多个线程   下次再有别的任务的时候,这个线程没有销毁掉,新的任务还是用这个线程去执行 

所以 开一定数量的线程放到那里  称为线程池。

线程池的类

ExecutorService接口  ThreadPlloExecutor类   Executors工具类

常见的用法

ExecutorService pool=Executors.newCachedThreadPool();创建线程池  

使用其execute(Runnabler)方法

结果  :0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 21 22 25 26 27 28 29 30 31 32 23 24 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 end
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 end
64 65 66 67 68 69 end

代码

import java.util.concurrent.*;
class ThreadPoolDemo{
	public static void main(String[]args) {
		ExecutorService pool=Executors.newCachedThreadPool();//创建线程池
		MyTask t1=new MyTask(50);//这些runnable对象就是执行run 
		MyTask t2=new MyTask(70);
		MyTask t3=new MyTask(80);//多个线程公用一定数量的线程
		//假设有几百个任务  并不需要开几百个线程
		pool.execute(t1);//执行第一个任务
		pool.execute(t2);//执行第二个任务
		pool.execute(t3);//执行第三个任务
		pool.shutdown();
	}
}
class MyTask implements Runnable{
	int n=10;
	public MyTask(int n) {this.n=n;}
	public void run() {
		for(int i=0;i<n;i++)System.out.print(i+" ");
		System.out.println("end");
	}
}

上面这个例子说明了线程池的好处  没有建立线程  创建了一个线程池  然后把任务定义  用线程池来执行任务   输出中是乱序的 也体现了“并发"的意味

 

Timer

有两个timer  java.util.Timer类    javax.swing.Timer类

它底层是线程,用线程循环的执行任务

import java.util.*;
class TimerTest{
	public static void main(String[] args) {
		Timer timer=new Timer("display");
		TimerTask task=new MyTask();
		timer.schedule(task,1000,1000);//
		//每隔一定时间执行任务 这个任务是 task
	}
}
class MyTask extends TimerTask{
	int n=0;
	public void run() {
		n++;
		System.out.println(new Date());
		System.out.println("---"+n);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值