Java 线程池概念使用

1.  ThreadLocal使用

public class Main {
	/**
	 *  每一个线程有个 一个ThreadLocal
	 *  为单独线程 共享数据
	 */
	public static void main(String[] args) {
		
		ThreadLocal<String> tl=new ThreadLocal<>();
		tl.set("xiaoming");  // 保存数据   
		
		System.out.println(tl.get());  // 获取保存的数据
		// 线程结束,必须释放,否则内存泄露
		// 什么叫做内存泄露:一块内存在堆中,没有栈变量指向的时候, 这个就是内存泄露
		// 什么叫内存溢出: 栈内存满了
		tl.remove();
		tl=null;
	}
}

2.  JUC

 jdk1.5 以后 Java 提供了JUC 处理多线程 
 线程安全容器
Vector,Hashtable 线程安全容器,使用syschronized实现
java.util.concurrent.* 下 ConcurrentHashMap 也实现线程安全的,使用Java8 CAS实现【底层C】
 都是 哈希表 :功能对比 
 java.util.concurrent.*  包下类 在高并发 效率高比 java.utils.hashmap 【简称 juc】

  public class Main {
	/**
	 *  每一个线程有个 一个ThreadLocal
	 *  为单独线程 共享数据
	 */
	public static void main(String[] args) {
	/**
		 * jdk1.5 以后 Java 提供了JUC 处理多线程 
		 *  线程安全容器
		 *  Vector,Hashtable 线程安全容器,使用syschronized实现
		 * java.util.concurrent.* 下 ConcurrentHashMap 也实现线程安全的,使用Java8 CAS实现【底层C】
		 *   都是 哈希表 :功能对比 
		 *    java.util.concurrent.*  包下类 在高并发 效率高比 java.utils.hashmap 【简称 juc】
		 */
		ConcurrentHashMap<String, String> con=new ConcurrentHashMap<>();
		con.put("name", "小明");
		System.out.println(con.get("name"));
	}
}

3.      任务接口

Callable : 返回值    Runnable :  没有返回值
任务接口使用:

package com.denganzhi.pp;

import java.awt.SystemColor;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main2 {

	  public static void main(String[] args) {
		
		  // 任务接口
		  // Callable : 返回值 
		  // Runnable :  没有返回值
		  
		  
		 //创建线程,这里必须要指定线程的个数
		  // ExecutorService  可以理解为 引擎,  任务调用者
		  ExecutorService or=Executors.newFixedThreadPool(1);
		   //执行线程获取返回值  submit 又返回值
	        Future<String> f=or.submit(new Callable<String>() {

				@Override
				public String call() throws Exception {
					// TODO Auto-generated method stub
					Thread.sleep(5000);
					return "返回值";
				}
			});
		 
	        try {
	        	System.out.println("线程是否结束:"+f.isDone());
	        	// 这里会阻塞
				String str=f.get();
				System.out.println(str);
			} catch (InterruptedException | ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
	        // 关闭 资源, 优雅关闭,把任务完成才关闭 , 不是立即关闭
	        or.shutdown();
	        System.out.println(or.isTerminated());  // 是否已经关闭,回收资源
	        
	       
	}
}

4.  线程池 Api

 逻辑核心:  一块CPU可以运行几个线程       8核 

 4.1.newFixedThreadPool
      // 当任务数量大于 线程池容量时候,线程池没有足够的Runnable去执行 任务数, 当线程有空闲的时候,自动从队列中取出任务
         // 使用场景:实际开发中,系统支持线程 上限,不能够随意   无限提供线程池
         // 固定容量线程池    相当于数组
         // 如何根据 cpu 核数 计算  创建线程数量

 public static void main(String[] args) {
		 /**
		  *  Executors: 线程池 父类接口
		  *   Jvm关闭,线程池生命周期结束
		  *   手动调用shutdown, 线程任务执行完毕以后,自动关闭线程池,如果不关闭,那么一直在
		  */
		 
		 // 当任务数量大于 线程池容量时候,线程池没有足够的Runnable去执行 任务数, 当线程有空闲的时候,自动从队列中取出任务
		 // 使用场景:实际开发中,系统支持线程 上限,不能够随意   无限提供线程池
		 // 固定容量线程池    相当于数组
		 // 如何根据 cpu 核数 计算  创建线程数量
		 ExecutorService service= Executors.newFixedThreadPool(5);
		 for (int i = 0; i <10; i++) {
			service.execute(new Runnable() {
				
				@Override
				public void run() {
				  try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				  System.out.println(" thread_name:"+ Thread.currentThread().getName());
				}
			});
		}
}

  4.2. newCachedThreadPool
          *   添加 任务,那么创建 新线程 , 自动扩容 
          *   创建的 线程 默认 空闲时间 60S,没有处理任务 ,那么自动销毁
          *   容量最大(Integer.MAX_VALUE)
          *   应用:用于测试 ,无限 任务 

 public static void main(String[] args) {
    /***
		  *   添加 任务,那么创建 新线程 , 自动扩容 
		  *   创建的 线程 默认 空闲时间 60S,没有处理任务 ,那么自动销毁
		  *   容量最大(Integer.MAX_VALUE)
		  *   应用:用于测试 ,无限 任务 
		  */
		 ExecutorService cachedPool= Executors.newCachedThreadPool();
		 for (int i = 0; i <5 ; i++) {
			cachedPool.execute(new Runnable() {
				@Override
				public void run() {
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				  System.out.println(" thread_name:"+ Thread.currentThread().getName());
				}
				
			});
		}
   }

  4.3. newScheduledThreadPool
          *   应用 : 用于定时执行 任务

 public static void main(String[] args) {
 	 /***
		  *   任务线程,没有用,没有试出来
		  *   应用 : 用于定时执行 任务
		  */
		 ScheduledExecutorService  service=Executors.newScheduledThreadPool(3);
		 
	   // 第一次任务执行间隔,多次任务执行间隔时间
		 System.out.println("start:"+new Date());
		 // 3个线程执行3个任务,4秒以后执行第二批
		 for (int i = 0; i <3 ; i++) { 
		 service.scheduleWithFixedDelay(new Runnable() {
			
			@Override
			public void run() {
				System.err.println(new Date());
				System.err.println(Thread.currentThread().getId());
			}
		}, 3, 4, TimeUnit.SECONDS);
	   }
   }

4.4. newSingleThreadExecutor
   // 单一 线程 容器, 只有一个 线程

  public static void main(String[] args) {
 		 // 单一 线程 容器, 只有一个 线程
	ExecutorService service1= Executors.newSingleThreadExecutor();
	for (int i = 0; i < 5; i++) {
		service1.execute(new Runnable() {
			
			@Override
			public void run() {
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			  System.out.println("线程数量唯一"+ Thread.currentThread().getId());
			}
		});
	}	
   }


  
  
  

发布了111 篇原创文章 · 获赞 123 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/dreams_deng/article/details/105104486