java中的线程(二)

本文深入探讨Java中的线程管理,包括三种单例模式(懒汉式、饿汉式、枚举实现),生产者消费者模式的实现,以及线程池的创建与拒接策略。详细解析了线程池的构造参数,并展示了newCachedThreadPool、newSingleThreadExecutor、newFixedThreadPool和newScheduledThreadPool的使用。同时,介绍了execute和submit方法的区别。
摘要由CSDN通过智能技术生成

单例模式的3中实现方法

第一种(懒汉式)

public class SingletonDemo1 {
	private static SingletonDemo1 instance=null;

	private SingletonDemo1() {   //构造方法私有
		
	}
	
	public static SingletonDemo1 getInstance() {
		if(instance==null) {
			instance=new SingletonDemo1();
		}
		return instance;
	}
}

这种方式线程不安全,我们在用的时候可以加锁

public class SingletonDemo1 {
	private static SingletonDemo1 instance=null;

	private SingletonDemo1() {   //构造方法私有
		
	}
	
	public static synchronized SingletonDemo1 getInstance() {
		if(instance==null) {
			instance=new SingletonDemo1();
		}
		return instance;
	}
}

使用:

SingletonDemo1 instance=SingletonDemo1.getInstance();

第二种(饿汉式)

public class SingletonDemo2 {
	
	private static SingletonDemo2 instance=new SingletonDemo2();	
	private Signel2() {
		
	}	
	public static SingletonDemo2 getInstance() {
		return instance;
	}
}

使用:

SingletonDemo2 istance=SingletonDemo2.getInstance;

第三种(枚举)

public enum SigletonDemo3 {
	INSTANCE;
}

使用:

SigletonDemo3 instance=SigletonDemo3.INSTANCE;

生产者消费者模式

理解:有一个容器,生产者生产某个东西放在这个容器中,消费者消费这个东西。
为什么要使用生产者消费者模式:在线程开发中,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。如果消费者的处理能力大于生产者,那么消费者就必须等待生产者,于是就引入了生产者消费者模式。

使用wait()与notifyAll()实现
假设生产者生产汉堡包,消费者消费汉堡包,在柜台上最多放下10个汉堡
汉堡类:


public class Hamburger {
	private String name;
	private int id;
	private static AtomicInteger i = new AtomicInteger(0);

	public Hamburger(String name) {
		this.name = name;
		id = i.incrementAndGet();
	}

	@Override
	public String toString() {
		return "Hamburger [name=" + name + ", id=" + id + "]";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getId() {
		return this.id;
	}

}

柜台:

public class Counter {
	// 用队列存储商品
	Deque<Hamburger> queue = new LinkedList<Hamburger>();
	private static int MAX_VALUE = 10; // 能存储的最大数量

	public synchronized void produce() throws Exception {
		while (queue.size() >= MAX_VALUE) {
			System.out.println("汉堡的数量已经足够多了,生产者停止生产汉堡,等待消费者消费汉堡");
			wait();
		}
		Hamburger h = new Hamburger("鸡腿堡");
		queue.offer(h);
		System.out.println("生产者产量了一个汉堡:" + h.getName() + "一共有汉堡数" + queue.size());
		notifyAll();
	}

	public synchronized void consume() throws Exception {
		while (queue.size() <= 0) {
			System.out.println("已经没有汉堡了,消费者停止消费,等待生产者生产");
			wait();
		}
		Hamburger h = queue.poll();
		System.out.println("消费者消费了一个汉堡:" + h.getName() + "剩余:" + queue.size());
		notifyAll();
	}

}

生产者的线程:

public class Producer implements Runnable {

	private Counter counter;

	public Producer(Counter counter) {
		this.counter = counter;
	}

	@Override
	public void run() {
		while (true) {
			try {
				counter.produce();
				Thread.sleep(200);
			} catch (Exception e) {
				e.getStackTrace();
			}
		}

	}

}

消费者的线程:

public class Consumer implements Runnable {

	private Counter counter;

	public Consumer(Counter counter) {
		this.counter = counter;
	}

	@Override
	public void run() {
		while (true) {
			try {
				counter.consume();
				Thread.sleep(300);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}

	}

}

测试:

public class Test {

	public static void main(String[] args) {
		Counter counter=new Counter();
		Thread p1=new Thread(new Producer(counter));
		Thread p2=new Thread(new Producer(counter));
		Thread p3=new Thread(new Producer(counter));
		Thread c1=new Thread(new Consumer(counter));
		Thread c2=new Thread(new Consumer(counter));
		Thread c3=new Thread(new Consumer(counter));
		Thread c4=new Thread(new Consumer(counter));
		
		p1.start();
		p2.start();
		p3.start();
		
		c1.start();
		c2.start();
		c3.start();
		c4.start();
	}
}

结果的部分截图:
在这里插入图片描述

线程池

线程池的好处:

  • 提高响应速度
  • 提高线程的可管理性
  • 防止服务器过载
  • 降低资源销毁

线程池的一个构造方法
在这里插入图片描述

参数理解:
corePoolSize:线程池中的核心线程数量,在没有用的时候也不会被收回.
maximumPoolSize:线程池中可以容纳的最大线程数量
keepAliveTime:线程池中的除了核心线程之外的其他的最长可以保留的时间,也就是非核心线程可以保留的最长的空闲时间
unit:计算时间的一个单位
workQueue:等待队列
handler:拒绝策略

执行

在这里插入图片描述

拒接策略

AbortPolicy不执行新任务,直接抛出异常,提示线程池已满,默认该方式。
CallerRunsPolicy:直接调用execute来执行当前任务。
DiscardPolicy:丢弃任务,但是不抛出异常。
DiscardOldestPolicy:抛弃任务队列中最旧的任务也就是最先加入队列的,再把这个新任务添加进去。先从任务队列中弹出最先加入的任务,空出一个位置,然后再次执行execute方法把任务加入队列

线程池的创建

newCachedThreadPool

创建一个可缓存线程池,如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,则新建线程

创建:
在这里插入图片描述
运行结果:
在这里插入图片描述

newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序执行。

创建:
在这里插入图片描述
结果:
在这里插入图片描述

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数。

创建:
在这里插入图片描述
运行:
在这里插入图片描述

newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行

创建:
在这里插入图片描述
运行:
在这里插入图片描述

提交方式

execute:

  • execute只能提交Runnable类型的任务,无返回值。
  • execute在执行任务时,如果遇到异常会直接抛出

submit
-submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
-submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值