大数据之Java基础(二十三):多线程--1

一、多线程

1.介绍
  • 进程:正在运行的程序
  • 线程:进程中的一个执行单元,一个程序至少有一个进程,每个进程至少有一个线程

2.程序运行原理
  • 分时调度:所有线程轮流使用CPU,平均分配使用时间
  • 抢占模式:优先让优先级高的线程使用CPU。如果优先级相同,那么会随机分配。Java使用的就是抢占式。

3.主线程
  • 执行main方法的线程称为主线程

4.Thread类
  • 构造函数
    • 空参构造函数:Thread();
    • String 参数构造函数:Thread(String threadName);

  • 常用方法
    • void start(); 线程开始,jvm调用该线程的run方法
    • void run(); 该线程要执行的操作;主要线程的代码,比如100次循环打印
    • static void sleep(); 静态方法,类名调用。线程休眠,暂停执行

5.创建线程

  • 方式一:继承Thread类
    • 定义一个线程类,例如MyTherad,继承Thread
    • 重写MyTherad类的run()方法
    • 创建线程对象,即MyTherad的对象
    • 调用对象的start方法
    • 代码展示:
public class MyThread  extends Thread{

	public MyThread()
	{
		
	}
	
	/*
	 * 通过构造函数,确定线程的名字
	 */
	public MyThread(String name)
	{
		super(name);
	}
	
	/*
	 * (重写run方法)
	 * @see java.lang.Thread#run()
	 */
	public void run()
	{
		for (int i = 0; i < 10; i++) {
			
			System.out.println(getName() + ": 正在执行" + i);
		}
		}
}

public class Demo1 {

	public static void main(String[] args) {
		
		
		MyThread myThread = new MyThread("Thread-0");
		myThread.start();
		
		for (int i = 0; i < 10; i++) {		
			System.out.println("main线程:正在执行:" + i);		
		}
		
	}	
}




  • 创建线程方式二:实现Runnable接口
    • 主要方法
      • run(); //线程执行的代码块
      • Thread(Runnable target); //构造线程时。可以传入runnable接口或者其子类
      • Therad(Runnable target,String name); //以Runnable构造线程对象,以name为线程的名字

    • 创建步骤
      • 定义类RunThread,实现Runnable接口
      • 实现接口的run()方法
      • 创建RunThread的对象
      • 创建Thread类对象,创建的时候,构造函数参数中,传入RunThread的对象
      • 执行Therad类的start方法,开启线程

    • 代码展示

public class MyRunThread implements Runnable{
	@Override
	public void run() {
		
		for (int j = 0; j < 10; j++) {
			
			System.out.println("执行" + j);
		}
	}	
}

public class Demo1 {

	public static void main(String[] args) {
		
		
//		MyThread myThread = new MyThread("Thread-0");
//		myThread.start();
		
		MyRunThread runTh = new MyRunThread();
		Thread t = new Thread(runTh, "thread-0");
		t.start();
		
		for (int i = 0; i < 10; i++) {		
			System.out.println("main线程:正在执行:" + i);		
		}
		
	}	
}


  • 两种创建方式的区别
    • Runnable接口方式避免了单继承的局限性,所以较为常用

  • 获取线程名称
    • static Thread currentTherad(); //静态方法。返回当前正在执行的线程对象
    • String getName(); //非静态方法。返回调用对象线程的名称
    • Thread.currentThread().getName(); //获取任意线程的名称


二、线程池

1.概念
  • 线程池其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多的资源。

2.使用Runnable创建线程池

  • 通常线程池是通过线程池工厂Executors类创建。
  • Excuetors类:线程池创建工厂类
    • public static ExcuetorService newFixedTheradPool(int nThreads); //参数为线程池中线程的个数,返回值为线程池对象
  • ExcuetorsService类:线程池类
    • Future<?> submit(Runnable task); //获取线程池中某一个线程对象,并执行;返回值用来记录线程任务执行完毕后产生的结果。

  • 线程池创建步骤
    • 创建线程池对象:Excuetors.newFixedTheradPool(5);
    • 创建runnable对象:new Runnable();
    • 关联runnable对象:submit(runnable);
    • 关闭线程池

  • 代码展示
//1.创建线程池工厂类
		ExecutorService es =  Executors.newFixedThreadPool(5);
		
		//2.创建Runnable对象,注意使用runnable创建的线程对象是没有返回值的
		Runnable task1 = new MyRunThread();
		Runnable task2 = new MyRunThread();
		Runnable task3 = new MyRunThread();
		
		//给线程池中的线程关联runnable任务
		Future<?> f1 =  es.submit(task1);
		Future<?> f2 =  es.submit(task2);
		Future<?> f3 =  es.submit(task3);
		
		//注意submit方法调用结束后,程序并不会终止,因为线程的关闭是由线程池控制的
		//关闭线程池
		es.shutdown();
		
		for (int i = 0; i < 10; i++) {		
			System.out.println("main线程:正在执行:" + i);		
		}



3.使用Callable创建带返回值地线程池

  • 与runnable接口相似,用来给线程池中的线程提供关联。其中call()方法,用来返回线程任务执行完毕后的结果。call方法会抛出异常。

  • ExecutorService线程池类的构造方法中有一个带参数Callable的
    • Future<T> submit(Callable<T> task); //将线程池中的线程与Callable进行关联。并执行Callable中的call()方法。
    • 返回值Future用于记录线程任务执行完毕后产生的结果

  • 创建步骤
    • 创建线程池对象:Executors.newFixedThreadPool(int count);
    • 创建Callable线程任务对象:
    • 将Callable线程任务对象与线程池中的线程进行关联
    • 关闭线程池

  • 代码展示
	//1.创建线程池对象
		ExecutorService es = Executors.newFixedThreadPool(5);
		
		//2.创建Callable线程任务接口
		Callable <String> call = new  Callable<String>() {

			@Override
			public String call() throws Exception {
				
				for(int i = 0 ; i <10 ; i++)
				{
					System.out.println("第" + i + "次");
				}
				return "ssss";
			}
		};
		
		//3.关联线程
		es.submit(call);
		es.submit(call);
		Future<String> f = es.submit(call);
		
		//4.打印返回值
		System.out.println(f.get());
		
		//5.关闭线程
		es.shutdown();
		
		//6.主线程打印循环
		for (int i = 0; i < 10; i++) {		
			System.out.println("main线程:正在执行:" + i);		
		}


4.线程池练习:返回两个数相加的结果

public class TestCallableThread implements Callable<Integer>{

	private int a;
	private int b;
	
	public TestCallableThread()
	{
		
	}
	
	public TestCallableThread(int a,int b)
	{
		this.a = a;
		this.b = b;
	}
	
	@Override
	public Integer call() throws Exception {
			
		return a+b;
	}

	
}

public class Demo2 {

	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		
		//1.创建线程池
		ExecutorService es = Executors.newFixedThreadPool(5);
		
		//2.创建线程任务
		Callable<Integer> call1 = new TestCallableThread(100, 200);
		Callable<Integer> call2 = new TestCallableThread(200, 200);
		Callable<Integer> call3 = new TestCallableThread(300, 200);
		
		//3.关联
		Future<Integer> f1 = es.submit(call1);
		Future<Integer> f2 = es.submit(call2);
		Future<Integer> f3 = es.submit(call3);
		
		//4.打印结果
		System.out.println("f1结果:" + f1.get());
		System.out.println("f2结果:" + f2.get());
		System.out.println("f3结果:" + f3.get());
		
		//5.关闭线程池
		es.shutdown();
		
	}
	
}



全文完!




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值