多线程相关补充

信号量

信号量,通俗也被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。信号量对可用许可进行计数,并采取相应的行动。拿到信号量许可的线程可以进入代码,否则就等待。
下面提供一个简单的信号控制例子:

public class ThreadTask {

	private int prompt = 1;

	public synchronized void transfer() {

	this.prompt++;

	this.notify();

	}

	public synchronized void operation() throws InterruptedException {

	while(this.prompt == 1) wait();

	this.prompt--;

	}

线程池

线程池主要用来解决线程生命周期开销问题和资源不足问题。通过对多个任务重复使用线程,线程创建的开销就被分摊到了多个任务上了,而且由于在请求到达时线程已经存在,所以消除了线程创建所带来的延迟。当一个服务器接受到大量短小线程的请求时,使用线程池技术是非常合适的,它可以大大减少线程的创建和销毁次数,提高服务器的工作效率。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadTask implements Runnable {
	 
		  public static void main(String[] args) { 
		    ExecutorService asd = Executors.newFixedThreadPool(5); //创建线程池 
		    asd.submit(new ThreadTask()); //向线程池中添加三个线程 
		    asd.submit(new ThreadTask()); 
		    asd.submit(new ThreadTask()); 
		    
		    asd.shutdown(); //关闭线程池
		  } 
		 String s=Thread.currentThread().getName();
			  for(int i = 0;i < 10;i++){ 
				  System.out.println( s+ "当前的值为:" + i); 
			  } 
		  } 

Lock接口及重入锁

JDK5中有一个Lock的默认实现:ReentrantLock:也就是重入锁,它的概念是在获得锁后可以重复获得该资源的锁。synchronized关键字是jvm虚拟机的关键字,在java中还有一个Lock接口,和Lock接口的实现类ReentrantLock(可重入锁)。 ReentrantLock可以实现和synchronized关键字相同的功能,而且更为灵活,在极端的情况下性能会更好一些。一起来看一下吧

private final ReentrantLock asd = new ReentrantLock();
   private int a;
	
	public void run() {
		int begin = 10000;
		while (begin > 0) {
			try {
				asd.lock();
				a ++;				
			} finally {
				asd.unlock();
			}
			begin --;
		}
	}
}

当线程执行到try块之后,首先通过asd.lock()获得锁,获得锁之后再执行a++,最后在finally语句块中通过asd的unlock方法释放锁。

ThreadLocal

我们需要在同一个线程中共享一个变量,一个最直接的办法就是创建一个共享的散列表,用线程对象作为键,需要线程中共享的变量作为值保存起来,每次使用散列表.get(Thread.currentThread())的方式获取。ThreadLocal用来解决多线程程序的并发问题。

public class ThreadTask {
	 ThreadLocal<Integer> a=new ThreadLocal<Integer>() {
		 protected Integer initialValue() {
			 return 10;
		 }
	 };
	 public int get() {
		 return a.get();
	 }
	 public void set() {
		 a.set(a.get()+1);
	 }

}

原子操作类

原子操作类相当于泛化的volatile变量,能够支持原子读取-修改-写操作,原子操作类在Java.util.concurrent.atomic包下,可以分为
原子更新基本类型
原子更新数组类型
原子更新引用
原子更新属性
使用原子的方式更新基本类型,Atomic包提供了以下3个类。
AtomicBoolean:原子更新布尔类型。
AtomicInteger:原子更新整型。
AtomicLong:原子更新Long类型。
以上3个类提供的方法几乎一模一样,以AtomicInteger为例常用方法如下:
int addAndGet(int delta): 以原子方式将输入的数值与实例中的值(AtomicInteger里的value)相加,并返回结果。
boolean compareAndSet(int expect,int update):如果输入的数值等于预期值,则以原子方式将该值设置为输入的值。

生产者-消费者模式

一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。
生产者仅仅在仓储未满时候生产,仓满则停止生产。
消费者仅仅在仓储有产品时候才能消费,仓空则等待。
当消费者发现仓储没产品可消费时候会通知生产者生产。
生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

package com.threadTask;

public class Add{
  class Product{    
    String name;    

    float price;    

     boolean isTrue=false;//是否开始生产
     
}
class Sale extends Thread{
	  
	    private Product p=null;
	      
	     public Sale(Product p){
	         this.p=p;
	     }
	     
	     public void run() {
	        int i=0;
	         while(true){
	             synchronized (p) {
	                 if(p.isTrue==false){
	                     
	                        if(i%2==0){
	                             p.name="糖";
	                            p.price=4;
	                             System.out.println("生产者生产");
	                        }else{
	                             p.name="饮料";
	                            p.price=2.5f;
	                             System.out.println("生产者生产了");
	                         }
	                         p.isTrue=true;
	                         i++;
	                     
	                  }else{
	                }
	            }    
	         }
	     }
	    
	 }
	 
	 class Custom extends Thread{
	     private Product p=null;
	      
	     public Custom(Product p){
	         this.p=p;
	     }
	     
	     public void run() {
	         
	         while(true){
	              synchronized (p) {    
	                 if(p.isTrue){
	                                      
	                          System.out.println("消费者生产了:"+p.name);
	                      
	                      p.isTrue=false;
	                  }else{
	                      p.notify();    //消费暂停,开始生产
	                  }
  }
	         }
	      }
	 }

	 public class Producer_Custom {
	 
	     
	      public void main(String[] args) {
	          
	          Product p=new Product();
	          
	         Sale sale=new Sale(p);    
	         sale.start();
	         Custom custom=new Custom(p);        
	         custom.start();
	     }
	 }
	 }



资历尚浅,还请包涵。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值