`
jiuyuehe
  • 浏览: 181187 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

边读边写【7】 ----java 多线程实战【Thread /Executors】

阅读更多
前面2个月一直忙碌,但是还是不忘在iteye 上发发帖子,写写文章。终于这周over了2套系统,剩下的时间基本上修改跟维护了。
在完成的一套“应用安装系统”后对多线程的理解又深了一点。
这里写出来,一来跟大家分享,二来让坛子里的大牛们指教指教,许多不足之处。
ps:看《maven 实战》看着看着就想睡觉,不知为什么?我一般看书很认真的。

ok。看看需求:

首先来实现一个多线程。简单的说就是在一个方法里头要完成6件事,6件事没有直接关联关系。不会因为一件事不完成导致下面的事情无法完成。都完成好了,就执行下一个方法。


线程的俩种实现方式,如果你的代码已经继承其他类了,就实现Runnable借口。这俩种方式的线程都是没有返回值的。

公司的代码不好贴,这里贴个变相的demo.

策略一:
public class TestThread {
	//
	private static int i;
	//这里就相当做事的方法,所以线程都做这一件事,同时做
	public void get(long name) {
		try {
			Thread.sleep(name);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("-----name-----"+name);
		i++;
	}
	//全部做完了。
	public int  over(int n){
		System.out.println("---over--"+n);
		return n;
	}
	
	//正开始做
	public void  ing (){
		final TestThread td = new TestThread();
		
		Thread tr4  = new Thread(new Runnable(){
			@Override
			public void run() {
				td.get(1500L);
			}
		});
		tr4.start();
		
		new Thread(){
			public void run (){
				td.get(500L);
			}
		}.start();
		
		
		new Thread(){
			public void run (){
				td.get(100L);
			}
		}.start();
	}
	
	public void show(){
		System.out.println("=======show()========");
	}
	

	public static void main(String[] args) {
                //调用
		final TestThread ted = new TestThread();
		ted.ing();
		//来一个守护线程,监视看是不是所以的事情都做完了。做完了守护线程也跟着挂了
		Thread tt = new Thread(){
		public void run (){
			while(true){
				try {    //守护线程每100ms检查一下各个线程的完成状况
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
                                     //方法运行了3此,代码多做了,这是守护线程也要挂了,挂之前。。。。。
				if(i==3){
					ted.show();
					ted.over(1);
				}
				
			}
		}		
		};
		tt.setDaemon(true);
		tt.start();
		
		//ted.show();	  这个方法会同是运行
		
	}
}


这样做貌似也能达到要求。但是有明显的缺点。
第一:线程同时运行,必须用守护线程去执行线程做完以后将要运行的方法:这是不可取的,守护线程会立刻跟这死掉,如果将要做的事情的需要消耗大量的时间,或者开销的话,那么这个方法是不会正确执行的。【不知道具体原因,希望大鸟能指点迷津。】
第二:程序一执行,各个线程独立跑,守护线程只能监视各个线程的状态而无法获取各个线程所执行的事情是否成功了。这是相当不理想的。

策略二:Callable
public class HasValueThread {
	public void a(){
		Callable ca1 = 	new Callable(){
			@Override
			public Object call() throws Exception {
				System.out.println("==yes===");
				return true;
			}
			
		};
		
		Date d1 = new Date();
		System.out.println("d1"+d1.toLocaleString());
		 //ExecutorService exec = Executors.newCachedThreadPool();//创建线程池 
		 ExecutorService exec = Executors.newFixedThreadPool(7);//创建线程池 
		  Callable c1 = new MyCallable("A",1000); 
          Callable c2 = new MyCallable("B",5000); 
          Callable c3 = new MyCallable("c",15000); 
         Future f1 =  exec.submit(c1);
         Future f2 =  exec.submit(c2);
         Future f4 =  exec.submit(c3);
         Future f3 =  exec.submit(ca1);
         
         try {
        	 
			System.out.println(f1.get().toString()+System.currentTimeMillis());
			System.out.println(f2.get().toString()+System.currentTimeMillis());
			System.out.println(f4.get().toString()+System.currentTimeMillis());
			System.out.println(f3.get().toString()+System.currentTimeMillis());
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
         exec.shutdown();
	}
	
	public static void main(String[] args) {
		new HasValueThread().a();
		
		System.out.println("------");
	}

}
class MyCallable implements Callable{ 
    private String oid; 
    private long n;
    MyCallable(String oid,long n) { 
            this.oid = oid; 
            this.n = n;
    } 

    @Override 
    public Object call() throws Exception { 
    	Date d2 = new Date();
		System.out.println("d2"+d2.toLocaleString());
    		Thread.sleep(n);
            return oid+"任务返回的内容"; 
    } 
} 


使用策略二的好处有:
第一:Callable 的好处是有返回值,也就是说一个线程是否成功完成了他的使命,我们可以从他的返回的结果中【自定义结果】中得知。
第二:ThreadPoolExecutor【写了一些并发包相关的博文放在草稿箱里没有发表出来,主要是怕错误太多 - -,贻笑大方】它提供了一个线程池,使用方法通常使用 Executors 工厂方法配置。 api说:线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。用Executor提交一个带返回值的Callable到ExecutorService里面。返回只类型是Futrue[未来,很有意思]。更有意思的是他会等全部的Callable执行完了以后在往下走,当然需要控制的是:
 //ExecutorService exec = Executors.newCachedThreadPool();//创建线程池 
		 ExecutorService exec = Executors.newFixedThreadPool(7);//创建线程池 

第一个newCachedThreadPool();他会启动n个线程来完成你的任务。他能自动线程回收。但是他的时间是60s.可以把这个demo跑下,发现让他sleep70秒他可以。这个问题我搞了很久没搞明白【求明白的分享】。所以我没用。用的是.newFixedThreadPool(7)参数能设置他的线程数。

总的来说还是那俩句话,一是分享,一是请教。谢谢


分享到:
评论

相关推荐

    Java多线程Executors批量执行数据实现限流

    Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...

    Python库 | more-executors-1.19.1.tar.gz

    资源分类:Python库 所属语言:Python 资源全名:more-executors-1.19.1.tar.gz 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Java中Executors类中几种创建各类型线程池

    Java中Executors类中几种创建各类型线程池方法及简单实例

    java面试题_多线程(68题).pdf

    1. 什么是线程? 2. 什么是线程安全和线程不安全? 3. 什么是⾃旋锁? 4. 什么是CAS? 5. 什么是乐观锁和悲观锁? 6. 什么是AQS? 7. 什么是原⼦操作?在Java Concurrency API中有哪些原⼦类(atomic classes)? 8. ...

    个人总结的深入java多线程开发

    看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一. 线程池 1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 3)使用线程池的风险: 4 4)有效使用线程池的原则 5...

    PyPI 官网下载 | more_executors-2.5.1-py2.py3-none-any.whl

    资源来自pypi官网。 资源全名:more_executors-2.5.1-py2.py3-none-any.whl

    PyPI 官网下载 | more_executors-1.1.0-py2.py3-none-any.whl

    资源来自pypi官网。 资源全名:more_executors-1.1.0-py2.py3-none-any.whl

    sparkexample

    火花示例./spark/bin/spark-submit --master yarn-cluster --executor-memory 40g --executor-cores 32 --num-executors 2 --jars s3n://my-path/wen/libjars/argparse4j- 0.4.3.jar --class org.sparkexample....

    Java并发编程中使用Executors类创建和管理线程的用法

    主要介绍了Java并发编程中使用Executors类创建和管理线程的用法,文中举了用其启动线程和设置线程优先级的例子,需要的朋友可以参考下

    Java并发编程中使用Executors类创建和管理线程的

    Java并发编程中使用Executors类创建和管理线程的用法共4页.pdf.zip

    第7章-JUC多线程v1.1.pdf

    JAVA线程基本学习, JAVA多线程的特性= 线程池: 本质上是一个对象池, 用来管理线程资源. 在任务执行前, 需要从线程池中拿出线程来执行. 在任务执行完成之后, 需要把线程放回线程池. 线程池好处: 降低资源的消耗...

    Java 并发核心编程

    本文的主题是关于具有java语言风格的Thread、synchronized、volatile,以及J2SE5中新增的概念,如锁(Lock)、原子性(Atomics)、并发集合类、线程协作摘要、Executors。开发者通过这些基础的接口可以构建高并发、线程...

    Java 7 Concurrency Cookbook

    Chapter 4, Thread Executors will teach the readers to delegate the thread management to executors. They allow running, managing, and getting the results of concurrent tasks. Chapter 5, Fork/Join ...

    java8源码-Android_Note:记录平常学习的一点知识!

    Java多线程 Java并发 [Java并发之线程池(二)之Executors] Java设计模式 Android UI控件篇 Android基础: Android自定义View篇 [自定义View--Canvas] [自定义View--Paint] [自定义View--Matrix] [自定义View--Path] ...

    tcp_thread_java.zip_Java 线程池_java TCP线程

    java简单线程池的实现,使用jdk的Executors.newFixedThreadPool方法来实现固定大小线程池

    java7hashmap源码-Rebuild-Java:再度重修JAVA

    java7 hashmap源码 README 虽然JAVASE看完了,但仔细一想,好像有很多似懂非懂的知识点,好像会,但仔细一想,却不会。 因此重修JAVA 着重看集合,IO,多线程 泛型例子-->来自java编程思想--P397 Holder.java ...

    azkaban-3.38安装包(已编译)

    7.登录mysql,将azkaban数据库下的executors表的active值改为1;否者启动程序会报azkaban.executor.ExecutorManagerException: No active executors found的异常。 use azkaban; update executors set active=1 ...

    Executors 使用实例

    java Executors 使用实例 concurrent.ExecutorService

Global site tag (gtag.js) - Google Analytics