zoukankan      html  css  js  c++  java
  • 0301 多线程

    创建多线程,除了继承Thread类之外,还可以实现Runnable接口

    是因为在继承Thread类的时候 我们创建Thread类对象时,既创建线程对象,又开启线程,这样就会导致耦合性太高。在实现Runnable接口时,这个接口的子类对象就只负责开启线程,让Thread类对象只负责创建线程对象,就实现了分工,就降低了耦合性。

    代码展示,首先创建一个类实现这个Runnable接口

    public class MyRunnable implements Runnable{
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		for(int i=0;i<100;i++){
    			System.out.println(Thread.currentThread().getName()+":"+i);
    		}
    	}
    	
    }
    

      代码展示,创建测试

    	public static void main(String[] args) {
    		//创建线程任务对象
    		MyRunnable my=new MyRunnable();
    		//创建线程对象
    		Thread t=new Thread(my);
    		Thread t2=new Thread(my);
    		//开启
    		t.start();
    		t2.start();
    	}
    

      Thread构造方法将线程传进去。

    这样就构成了Thread只负责创建线程对象,Runnable只负责创建线程

    避免了继承Thread类的单继承的局限性

    那我们为了实现多线程,去专门创建一个类,是不是有点浪费

    那我们可以使用匿名内部类去实现多线程的操作

    代码展示

    	public static void main(String[] args) {
    		//继承Thread类的方式
    		new Thread(){
    			public void run() {
    				for(int i=0;i<100;i++){
    					System.out.println(Thread.currentThread().getName()+":"+i);
    				}
    			}
    		}.start();
    		//实现runnable
    		Runnable r=new Runnable() {
    			
    			@Override
    			public void run() {
    				// TODO Auto-generated method stub
    				for(int i=0;i<100;i++){
    					System.out.println(Thread.currentThread().getName()+":"+i);
    				}
    			}
    		};
    		//创建线程对象开启线程
    		new Thread(r).start();
    	}
    

      上述代码中分别写了Thread类的匿名内部类的创建线程的方式和runnable匿名内部类的创建线程的方式

    线程池

    创建线程池可以指定创建几条线程,当开启线程的时候会自动给线程池中空闲的线程去执行

    使用线程池的方式

    (1)runnable接口

    Executors类中有一个public static ExecutorService newFixedThreadPool(int nThreads) 方法,返回一个线程池对象

    ExecutorService 线程池类中有一个 submit方法获取某一个线程对象

    ExecutorService 线程池类中有一个shutdown方法 关闭线程池

    代码展示

    我们用runnable接口来实现

    首先创建一个runnable子类继承这个runnable接口

    public class MyRunnable implements Runnable{
    
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		for(int i=0;i<100;i++){
    			System.out.println(Thread.currentThread().getName()+":"+i);
    		}
    	}
    	
    }
    

      测试

    	public static void main(String[] args) {
    		//获取线程池对象
    		ExecutorService  es=Executors.newFixedThreadPool(2);
    		//描述线程任务
    		MyRunnable r=new MyRunnable();
    		//将线程任务对象交给线程池执行
    		es.submit(r);
    		es.submit(r);
    		es.submit(r);
    		//销毁线程池
    		es.shutdown();
    	}
    

      上述代码中 线程池中只有两条线程,但是我们现编提交给线程池三条任务,那就会先执行完前两条线程任务之后再执行最后一条线程

    (2)callable接口

    该接口可以返回线程任务结束以后所产生的结果,该接口有一个泛型,就是该线程返回值是什么类型 这个泛型就写什么类型

    Future<F>接口 用来记录线程任务执行完毕后产生的结果

    get() 获取Future对象中封装的数据结果

    代码展示,与上述步骤一样,只不过就是多了一个返回值

    public class MyCallable implements Callable<String>{
    
    	@Override
    	public String call() throws Exception {
    		// TODO Auto-generated method stub
    		return "abc";
    	}
    
    	
    }
    

      创建测试

    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		//获得线程池对象
    		ExecutorService es=Executors.newFixedThreadPool(2);
    		//创建线程任务
    		MyCallable c=new MyCallable();
    		//将线程任务交给线程池执行
    		Future<String> f=es.submit(c);
    		//获取返回值
    		String str=f.get();
    		System.out.println(str);
    		//销毁线程池
    		es.shutdown();
    	}
    

     

    例举,用线程求1-n的和

    创建一个类实现Callable接口

    public class GetSum implements Callable<Integer>{
    
    	private int number;
    	
    	public GetSum(int number) {
    		super();
    		this.number = number;
    	}
    
    	public GetSum() {
    		super();
    	}
    
    	public Integer call() throws Exception {
    		int sum=0;
    		for(int i=0;i<=number;i++){
    			sum=sum+i;
    		}
    		return sum;
    	}
    
    	
    }
    

      创建测试类

    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		//获取线程池对象
    		ExecutorService es=Executors.newFixedThreadPool(2);
    		//创建线程任务
    		GetSum g=new GetSum(100);
    		GetSum gs=new GetSum(200);
    		
    		//执行
    		Future<Integer> f1=es.submit(g);
    		Future<Integer> f2=es.submit(gs);
    		System.out.println(f1.get());
    		System.out.println(f2.get());
    		//关闭
    		es.shutdown();
    	}
    

      这样就同时出了1-100的和  and 1-200的和

  • 相关阅读:
    unity, sceneview 中拾取球体gizmos
    C#, float.ToString()的一个坑
    unity, SerializedObject.FindProperty不要写在Editor的OnEnable里,要写在OnInspectorGUI里
    unity, 查看.anim中的动画曲线(和帧)
    unity, Graphics.Blit (null, null, mat,0);
    unity, GL.TexCoord or GL.Color must put before GL.Vertex!!!
    (MyEclipse) MyEclipse完美破解方法(图)
    博客园kubrick主题
    sina微博加入到博客园
    MyEclipse 2014 破解图文详细教程
  • 原文地址:https://www.cnblogs.com/-gongxue/p/14464082.html
Copyright © 2011-2022 走看看