多线程创建的四种方式

线程的生命周期
在这里插入图片描述
线程状态转换
在这里插入图片描述
Thread类的常用方法在这里插入图片描述
线程优先级
在这里插入图片描述
线程创建方式一:继承Thread类,重写run方法

//1、继承Thread类
public class MyThread extends Thread{
	//2、重写run方法
	public void run() {
		for(int i=0;i<100;i++) {
			if(i%2 == 0) {
				System.out.println(i);
			}
		}
	}
	public static void main(String[] args) {
		//3、创建Thread类的子类对象
		MyThread myThread = new MyThread();
		//4、调用start方法启动线程
		myThread.start();
	}
}

线程创建方式二:实现Runnable接口,实现run方法

class MyRunnable implements Runnable{
	@Override
	public void run() {
		for(int i=0;i<10;i++) {
			if(i % 2 == 0) {
				System.out.println(i);
			}
		}
	}
	public static void main(String[] args) {
		MyRunnable myRunnable = new MyRunnable();
		Thread thread = new Thread(myRunnable);
		thread.start();
	}
}

线程创建方式三:实现Callable接口,实现call方法

1、创建一个类是实现Callable
2、实现call方法,此线程需要执行的操作声明在call中,可以有返回值
3、创建Callable接口实现类对象
4、将此是实现类对象作为参数传递非FutureTask构造器,创建FutureTask的对象
5、将FutureTask的对象作为参数传递到THread类的构造器中,创建Thread类对象,调用start方法
6、获取Callable中call的返回值 *
get()方法返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值

1、如何理解Callable接口比Runnable接口强大

  • call方法有返回值
  • call可以抛出异常信息,被外面的操作捕获io,获取异常信息
  • Callable支持泛型
public class CallableTest implements Callable{
	@Override
	public Object call() throws Exception {
		int sum = 0;
		for(int i=0;i<10;i++) {
			if(i%2==0) {
				System.out.println(i);
				sum+=i;
			}
		}
		return sum;
	}
	public static void main(String[] args) {
		CallableTest callable = new CallableTest();
		FutureTask<Integer> task = new FutureTask<Integer>(callable);
		new Thread(task).start();//	启动线程	
		try {
			//get()方法返回值即为FutureTask构造器参数Callable实现类重写的call()的返回值
			Integer integer = task.get();
			System.out.println(integer);
		} catch (InterruptedException | ExecutionException e) {
			e.printStackTrace();
		}
	}
}

线程创建方式四:线程池创建线程
好处:
1、提高了响应速度(减少了创建线程的时间)
2、降低资源消耗(重复利用线程池中的线程,不需要每次都创建)
3、便于线程管理

corePoolSize:核心池大小
maximumPoolSize:最大线程数
keepAliveTime:线程没有任务时最多保持多长时间后会终止

class MyDemo implements Runnable{
	@Override
	public void run() {
		for(int i = 0;i<10;i++) {
			if(i%2==0) {
				System.out.println(i);
			}
		}	
	}	
}
class MyDemo1 implements Runnable{
	@Override
	public void run() {
		for(int i = 0;i<10;i++) {
			if(i%2!=0) {
				System.out.println(i);
			}
		}	
	}	
}
public class ThreadPool {
	public static void main(String[] args) {
		//1、提供指定线程数量的线程池
		ExecutorService service = Executors.newFixedThreadPool(10);
		ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
		//设置线程池的属性
//		service1.setCorePoolSize(corePoolSize);
//		service1.setKeepAliveTime(time, unit);
//		service1.setMaximumPoolSize(maximumPoolSize);
		//2、执行指定的线程操作。需要提供实现Runnable接口或者Callable接口的实现类对象
		service.execute(new MyDemo());//适合使用Runnable
		service.execute(new MyDemo1());//适合使用Runnable
		//service.submit();适合使用Callable接口
		//3、关闭连接池
		service.shutdown();
	}
}

线程安全问题解决

方式一:同步代码块(
	Synchronized(同步监视器){
		//需要同步的代码块
}
操作共享数据的代码,即为需要被同步的代码

共享数据:多个线程共同操作的变量	

同步监视器:俗称,锁,任何一个对象均可充当锁

要求:多个线程必须共用同一把锁

在实现Runnable接口时,可以使用this充当同步监视器,

继承Thread类时,了可以使用类的字节码文件充当监视器

方式二:同步方法
	如果操作共享数据的代码完整的声明在一个方法中添加synchronized
同步方法任然设计到同步监视器,只是不需要我们显示声明,
非静态的同步方法,监视器时:this
静态同步方法,同步监视器是:当前类本身

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值