JavaDay18-多线程(三)
5、题目:抽奖箱。(我的实现方法)
- 抽奖池中奖励的金额为:
- 创建两个抽奖箱名称分别为”抽奖箱1“”抽奖箱2“
- 随机从抽奖池中抽取元素并打印在控制台上,格式如下:
抽奖箱1又产生了一个10元大奖
抽奖箱1又产生了一个100元大奖
抽奖箱2又产生了一个800元大奖
...
public class Question {
public static void main(String[] args) {
Draw draw = new Draw();
Thread thread1 = new Thread(draw);
Thread thread2 = new Thread(draw);
thread1.setName("抽奖箱1");
thread2.setName("抽奖箱2");
thread1.start();
thread2.start();
}
}
import java.util.Random;
//不知道为什么这种实现方式停不下来,会一直运行????但输出结果是对的
//知道了!!count没有自增...
public class Draw implements Runnable{
private static int[] draw= {10,5,20,50,100,500,200,800,2,80,300,700};
private static int count;
@Override
public void run() {
while (true){
synchronized (Draw.class){
if (count==draw.length-1){
break;
}else {
Random random = new Random();
int i = random.nextInt(draw.length-1);
if (draw[i]!=0){
int price=draw[i];
draw[i]=0;
System.out.println(Thread.currentThread().getName()+"又产生了一个"+price+"元大奖");
count++;
}
}
}
}
}
}
6、题目:抽奖箱。(老师的实现方法)
- 抽奖池中奖励的金额为:
- 创建两个抽奖箱名称分别为”抽奖箱1“”抽奖箱2“
- 随机从抽奖池中抽取元素并打印在控制台上,格式如下:
抽奖箱1又产生了一个10元大奖
抽奖箱1又产生了一个100元大奖
抽奖箱2又产生了一个800元大奖
...
public class Question {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,10,5,20,50,100,500,200,800,2,80,300,700);
Draw draw = new Draw(list);
Thread thread1 = new Thread(draw);
Thread thread2 = new Thread(draw);
thread1.start();
thread2.start();
}
}
import java.util.ArrayList;
import java.util.Collections;
//用集合存储{10,5,20,50,100,500,200,800,2,80,300,700}
public class Draw implements Runnable{
//定义变量
ArrayList<Integer> list;
//传递参数
public Draw(ArrayList<Integer> list) {
this.list = list;
}
@Override
public void run() {
while (true){
synchronized (Draw.class){
if (list.size()==0){
break;
}else {
Collections.shuffle(list);//打乱顺序
int i= list.remove(0);//删除抽到的元素
System.out.println(Thread.currentThread().getName()+"又产生了一个"+i+"元大奖");
}
}
}
}
}
7、题目:抽奖箱(二)。
- 抽奖池中奖励的金额为:
- 创建两个抽奖箱名称分别为”抽奖箱1“”抽奖箱2“
- 每次抽的过程中不打印,抽完一次性打印,打印格式如下:
在此次抽奖抽奖过程中,抽奖箱1一共产生了6个奖项。
分别为:10,5,20,100,500,800最高奖项为800,总计金额为***元
...
public class Question {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,10,5,20,50,100,500,200,800,2,80,300,700);
Draw2 draw = new Draw2(list);
Thread thread1 = new Thread(draw);
Thread thread2 = new Thread(draw);
thread1.setName("抽奖箱1");
thread2.setName("抽奖箱2");
thread1.start();
thread2.start();
}
}
import java.util.ArrayList;
import java.util.Collections;
//用集合存储{10,5,20,50,100,500,200,800,2,80,300,700}
public class Draw2 implements Runnable{
//定义变量
ArrayList<Integer> list;
//传递参数
public Draw2(ArrayList<Integer> list) {
this.list = list;
}
static ArrayList<Integer> list1 = new ArrayList<>();
static ArrayList<Integer> list2 = new ArrayList<>();
@Override
public void run() {
while (true){
synchronized (practise.question6.Draw.class){
if (list.size()==0){
int max=0;
int count=0;
int sum=0;
if ("抽奖箱1".equals(Thread.currentThread().getName())){
for (Integer integer : list1) {
if (integer>max){
max=integer;
}
count++;
sum+=integer;
}
System.out.println("在此次抽奖抽奖过程中,抽奖箱1一共产生了"+count+"个奖项,分别是:"+list1+"最高奖项为"+max+"最高奖项为"+sum);
}else {
for (Integer integer : list2) {
if (integer>max){
max=integer;
}
count++;
sum+=integer;
}
System.out.println("在此次抽奖抽奖过程中,抽奖箱2一共产生了"+count+"个奖项,分别是:"+list2+"最高奖项为"+max+"最高奖项为"+sum);
}
break;
}else {
Collections.shuffle(list);//打乱顺序
int i= list.remove(0);//删除抽到的元素
if ("抽奖箱1".equals(Thread.currentThread().getName())){
list1.add(i);
}else {
list2.add(i);
}
}
}
}
}
}
8、题目:抽奖箱(二)优化。
- 抽奖池中奖励的金额为:
- 创建两个抽奖箱名称分别为”抽奖箱1“”抽奖箱2“
- 每次抽的过程中不打印,抽完一次性打印,打印格式如下:
在此次抽奖抽奖过程中,抽奖箱1一共产生了6个奖项。
分别为:10,5,20,100,500,800最高奖项为800,总计金额为***元
...
import java.util.ArrayList;
import java.util.Collections;
/*
内存分析:
每一条线程都会有自己的线程栈,
在本测试类中一共有三个线程栈:main、thread1、thread2
在线程栈中存放了run()方法,
和run()方法中创建的变量和集合。
创建的draw对象存放在堆中。
*/
public class Question {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,10,5,20,50,100,500,200,800,2,80,300,700);
Draw3 draw = new Draw3(list);
Thread thread1 = new Thread(draw);
Thread thread2 = new Thread(draw);
thread1.setName("抽奖箱1");
thread2.setName("抽奖箱2");
thread1.start();
thread2.start();
}
}
import java.util.ArrayList;
import java.util.Collections;
//用集合存储{10,5,20,50,100,500,200,800,2,80,300,700}
public class Draw3 implements Runnable{
//定义变量
ArrayList<Integer> list;
//传递参数
public Draw3(ArrayList<Integer> list) {
this.list = list;
}
@Override
public void run() {
//线程会创建自己的list,不需要手动创建多个list
ArrayList<Integer> list1 = new ArrayList<>();
while (true){
synchronized (practise.question6.Draw.class){
if (list.size()==0){
/*int max=0;
int count=0;
int sum=0;
for (Integer integer : list1) {
if (integer>max){
max=integer;
}
count++;
sum+=integer;
}*/
//可以用collections中的方法
int max=Collections.max(list1);
int count=list1.size();
int sum=0;
for (Integer integer : list1) {
sum+=integer;
}
System.out.println("在此次抽奖抽奖过程中,"+Thread.currentThread().getName()+"一共产生了"+count+"个奖项,分别是:"+list1+"最高奖项为"+max+"最高奖项为"+sum);
break;
}else {
Collections.shuffle(list);//打乱顺序
int i= list.remove(0);//删除抽到的元素
list1.add(i);
}
}
}
}
}
9、题目:抽奖箱(三)。
- 抽奖池中奖励的金额为:
- 创建两个抽奖箱名称分别为”抽奖箱1“”抽奖箱2“
- 每次抽的过程中不打印,抽完一次性打印
- 比较两条线程:抽奖箱产生了最大奖项,金额为**元。
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Question {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list,10,5,20,50,100,500,200,800,2,80,300,700);
Draw4 draw = new Draw4(list);
FutureTask<Integer> futureTask1 = new FutureTask<>(draw);
FutureTask<Integer> futureTask2 = new FutureTask<>(draw);
Thread thread1 = new Thread(futureTask1);
Thread thread2 = new Thread(futureTask2);
thread1.setName("抽奖箱1");
thread2.setName("抽奖箱2");
thread1.start();
thread2.start();
Integer i1 = futureTask1.get();
Integer i2 = futureTask2.get();
if (i1>i2){
System.out.println(thread1.getName()+"产生了最大奖项,金额为"+i1);
}else {
System.out.println(thread2.getName()+"产生了最大奖项,金额为"+i2);
}
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Callable;
//用集合存储{10,5,20,50,100,500,200,800,2,80,300,700}
public class Draw4 implements Callable<Integer> {
//定义变量
ArrayList<Integer> list;
//传递参数
public Draw4(ArrayList<Integer> list) {
this.list = list;
}
@Override
public Integer call() throws Exception {
ArrayList<Integer> list1 = new ArrayList<>();
while (true) {
synchronized (practise.question6.Draw.class) {
if (list.size() == 0) {
break;
} else {
Collections.shuffle(list);//打乱顺序
int i = list.remove(0);//删除抽到的元素
list1.add(i);
}
}
}
if (list1.size()==0){
return 0;
}else {
return Collections.max(list1);
}
}
}
十、线程池
10.1 线程池--回收线程:
1、线程池中线程数量无上限
public static ExecutorService newCachedThreadPool()
2、线程池中线程数量人为固定上限上限
public static ExecutorService newFixedThreadPool(int nThreads)
3、线程池工具类--Executors
10.2 核心原理:
1、创建线程池后,池中是空的
2、提交任务时,池子会创建新的线程;任务执行完后,线程还给池子;下一次提交任务时,不需要创建新的线程,直接复用已有的线程即可
3、如果提交任务时线程池中没有空闲的线程,任务只能排队等待,无法创建新的线程
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolTest {
public static void main(String[] args) {
/*//创建线程池对象-无上限
ExecutorService pool = Executors.newCachedThreadPool();*/
//自定义最多只能创建3个线程
ExecutorService pool = Executors.newFixedThreadPool(3);
//提交任务(5条任务,会创建5个线程)
pool.submit(new ThreadPool());
pool.submit(new ThreadPool());
pool.submit(new ThreadPool());
pool.submit(new ThreadPool());
pool.submit(new ThreadPool());
//销毁线程池
pool.shutdown();
}
}
public class ThreadPool implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"----------");
}
}
10.3 自定义线程池
ThreadPoolExecutor pool = new ThreadPoolExecutor(核心线程数,最大线程数,空闲线程最大存活时间,时间单位,任务队列,创建线程工厂,任务拒绝策略);
参数一:核心线程数--不能小于0
参数二:最大线程数--不能小于0,最大数量>=核心线程数
参数三:空闲线程最大存活时间--不能小于0
参数四:时间单位--用TimeUnit指定
参数五:任务队列--不能为null
参数六:创建线程工厂--不能为null
参数七:任务拒绝策略--不能为null
细节:核心线程数+临时线程数=最大线程数
import java.util.concurrent.*;
public class ThreadPoolTest {
public static void main(String[] args) throws InterruptedException {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3,//核心线程数--不能小于0
6,//临时线程数==3
60,//60没有工作就会被摧毁
TimeUnit.SECONDS,//单位:秒
new ArrayBlockingQueue<>(3),//阻塞队列,指定队列的长度--ArrayBlockingQueue,无线长度--LinkedBlockingQueue
Executors.defaultThreadFactory(),//创建线程工厂--底层是new Thread
new ThreadPoolExecutor.AbortPolicy()//任务拒绝策略--AbortPolicy是ThreadPoolExecutor的内部类
);//假如有10个任务到来时,先创建核心线程处理3个任务,后将第4-6个任务任务放在阻塞队列中排队,当阻塞队列满了时,创建临时线程执行第7-9个任务,此时还有1个任务,就用到了任务拒绝策略
ThreadPool thread = new ThreadPool();
pool.submit(thread);
Thread.sleep(1000);
pool.submit(thread);
Thread.sleep(1000);
pool.submit(thread);
}
}
public class ThreadPool implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"-----");
}
}

浙公网安备 33010602011771号