public class MyRunnable implements Runnable{
			@Override
			public void run() {
				for (int i = 1; i <= 100; i++) {
					System.out.println(Thread.currentThread().getName() + "---" + i);
				}
			}
			}
				
			
				
			import java.util.concurrent.ExecutorService;
			import java.util.concurrent.Executors;

			public class MyThreadPoolDemo {
				public static void main(String[] args) throws InterruptedException {
				/*
			public static ExecutorService newCachedThreadPool()             创建一个没有上限的线程池
			public static ExecutorService newFixedThreadPool (int nThreads) 创建有上限的线程池
			*/


			//1.获取线程池对象
			ExecutorService pool1 = Executors.newFixedThreadPool(3);
			//2.提交任务
			pool1.submit(new MyRunnable());
			pool1.submit(new MyRunnable());
			pool1.submit(new MyRunnable());
			pool1.submit(new MyRunnable());
			pool1.submit(new MyRunnable());
			pool1.submit(new MyRunnable());


			//3.销毁线程池
			//pool1.shutdown();


			}
			}
				
			
				
			import java.util.concurrent.ArrayBlockingQueue;
			import java.util.concurrent.Executors;
			import java.util.concurrent.ThreadPoolExecutor;
			import java.util.concurrent.TimeUnit;

			public class MyThreadPoolDemo1 {
				public static void main(String[] args){

				/*
			ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor
			(核心线程数量,最大线程数量,空闲线程最大存活时间,任务队列,创建线程工厂,任务的拒绝策略);

			参数一:核心线程数量              不能小于0
			参数二:最大线程数                不能小于0,最大数量 >= 核心线程数量
			参数三:空闲线程最大存活时间       不能小于0
			参数四:时间单位                  用TimeUnit指定
			参数五:任务队列                  不能为null
			参数六:创建线程工厂              不能为null
			参数七:任务的拒绝策略             不能为null
			*/

			ThreadPoolExecutor pool = new ThreadPoolExecutor(
					3,  //核心线程数量,能小于0
					6,  //最大线程数,不能小于0,最大数量 >= 核心线程数量
					60,//空闲线程最大存活时间
					TimeUnit.SECONDS,//时间单位
					new ArrayBlockingQueue<>(3),//任务队列
					Executors.defaultThreadFactory(),//创建线程工厂
					new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略
			);

			}
			}
				
			
				
			public class MyThreadPoolDemo2 {
				public static void main(String[] args) {
			//向Java虚拟机返回可用处理器的数目
			int count = Runtime.getRuntime().availableProcessors();
			System.out.println(count);
			}
	}		
				
			
				
			public class MyThread extends Thread {

			//第一种方式实现多线程,测试类中MyThread会创建多次,所以需要加static
			static int ticket = 1000;

			@Override
			public void run() {
				//1.循环
				while (true) {
					//2.同步代码块
					synchronized (MyThread.class) {
						//3.判断共享数据(已经到末尾)
						if (ticket == 0) {
							break;
						} else {
							//4.判断共享数据(没有到末尾)
							try {
								Thread.sleep(3000);
							} catch (InterruptedException e) {
								e.printStackTrace();
							}
							ticket--;
							System.out.println(getName() + "在卖票,还剩下" + ticket + "张票!!!");
						}
					}
				}
			}
			}
				
			
				
			public class Test {
			public static void main(String[] args) {
		   /*
				一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒,
				要求:请用多线程模拟卖票过程并打印剩余电影票的数量
			*/

			//创建线程对象
			MyThread t1 = new MyThread();
			MyThread t2 = new MyThread();

			//给线程设置名字
			t1.setName("窗口1");
			t2.setName("窗口2");

			//开启线程
			t1.start();
			t2.start();

			}
			}
				
			
				
			import com.itheima.test1.MyThread;

			public class MyRunable implements Runnable {

			//第二种方式实现多线程,测试类中MyRunable只创建一次,所以不需要加static
			int count = 100;

			@Override
			public void run() {
				//1.循环
			while (true) {
				//2.同步代码块
				synchronized (MyThread.class) {
					//3.判断共享数据(已经到末尾)
					if (count < 10) {
						System.out.println("礼物还剩下" + count + "不再赠送");
						break;
					} else {
						//4.判断共享数据(没有到末尾)
						count--;
						System.out.println(Thread.currentThread().getName() + "在赠送礼物,还剩下" + count + "个礼物!!!");
					}
				}
			}
			}
			}
				
			
				
			public class Test {
			public static void main(String[] args) {
			/*
				有100份礼品,两人同时发送,当剩下的礼品小于10份的时候则不再送出,
				利用多线程模拟该过程并将线程的名字和礼物的剩余数量打印出来.
			*/

			//创建参数对象
			MyRunable mr = new MyRunable();

			//创建线程对象
			Thread t1 = new Thread(mr,"窗口1");
			Thread t2 = new Thread(mr,"窗口2");

			//启动线程
			t1.start();
			t2.start();
			}
			}
				
			
				
			import com.itheima.test1.MyThread;

			public class MyRunable implements Runnable {

			//第二种方式实现多线程,测试类中MyRunable只创建一次,所以不需要加static
			int number = 1;

			@Override
			public void run() {
				//1.循环
				while (true) {
					//2.同步代码块
					synchronized (MyThread.class) {
						//3.判断共享数据(已经到末尾)
						if (number > 100) {
							break;
						} else {
							//4.判断共享数据(没有到末尾)
							if(number % 2 == 1){
								System.out.println(Thread.currentThread().getName() + "打印数字" + number);
							}
							number++;
						}
					}
				}
			}
			}
				
			
				
			public class Test {
			public static void main(String[] args) {
			/*
			   同时开启两个线程,共同获取1-100之间的所有数字。
			   要求:将输出所有的奇数。
			*/


			//创建参数对象
			MyRunable mr = new MyRunable();

			//创建线程对象
			Thread t1 = new Thread(mr,"线程A");
			Thread t2 = new Thread(mr,"线程B");

			//启动线程
			t1.start();
			t2.start();
			}
			}
				
			
				
			import java.util.Random;

			public class MyThread extends Thread{

			//共享数据
			//100块,分成了3个包
			static double money = 100;
			static int count = 3;

			//最小的中奖金额
			static final double MIN = 0.01;

			@Override
			public void run() {
				//同步代码块
			synchronized (MyThread.class){
				if(count == 0){
					//判断,共享数据是否到了末尾(已经到末尾)
					System.out.println(getName() + "没有抢到红包!");
				}else{
					//判断,共享数据是否到了末尾(没有到末尾)
					//定义一个变量,表示中奖的金额
					double prize = 0;
					if(count == 1){
						//表示此时是最后一个红包
						//就无需随机,剩余所有的钱都是中奖金额
						prize = money;
					}else{
						//表示第一次,第二次(随机)
						Random r = new Random();
						//100 元   3个包
						//第一个红包:99.98
						//100 - (3-1) * 0.01
						double bounds = money - (count - 1) * MIN;
						prize = r.nextDouble(bounds);
						if(prize < MIN){
							prize = MIN;
						}
					}
					//从money当中,去掉当前中奖的金额
					money = money - prize;
					//红包的个数-1
					count--;
					//本次红包的信息进行打印
					System.out.println(getName() + "抢到了" + prize + "元");
				}
			}
			}
			}
				
			
				
			public class Test {
			public static void main(String[] args) {
			/*
				微信中的抢红包也用到了多线程。
				假设:100块,分成了3个包,现在有5个人去抢。
				其中,红包是共享数据。
				5个人是5条线程。
				打印结果如下:
					XXX抢到了XXX元
					XXX抢到了XXX元
					XXX抢到了XXX元
					XXX没抢到
					XXX没抢到
			*/

			//创建线程的对象
			MyThread t1 = new MyThread();
			MyThread t2 = new MyThread();
			MyThread t3 = new MyThread();
			MyThread t4 = new MyThread();
			MyThread t5 = new MyThread();

			//给线程设置名字
			t1.setName("小A");
			t2.setName("小QQ");
			t3.setName("小哈哈");
			t4.setName("小诗诗");
			t5.setName("小丹丹");

			//启动线程
			t1.start();
			t2.start();
			t3.start();
			t4.start();
			t5.start();
			}
			}
				
			
				
			import java.math.BigDecimal;
			import java.math.RoundingMode;
			import java.util.Random;

			public class MyThread extends Thread{

				//总金额
				static BigDecimal money = BigDecimal.valueOf(100.0);
				//个数
				static int count = 3;
				//最小抽奖金额
				static final BigDecimal MIN = BigDecimal.valueOf(0.01);

				@Override
				public void run() {
				synchronized (MyThread.class){
				if(count == 0){
					System.out.println(getName() + "没有抢到红包!");
				}else{
					//中奖金额
					BigDecimal prize;
					if(count == 1){
						prize = money;
					}else{
						//获取抽奖范围
						double bounds = money.subtract(BigDecimal.valueOf(count-1).multiply(MIN)).doubleValue();
						Random r = new Random();
						//抽奖金额
						prize = BigDecimal.valueOf(r.nextDouble(bounds));
					}
					//设置抽中红包,小数点保留两位,四舍五入
					prize = prize.setScale(2,RoundingMode.HALF_UP);
					//在总金额中去掉对应的钱
					money = money.subtract(prize);
					//红包少了一个
					count--;
					//输出红包信息
					System.out.println(getName() + "抽中了" + prize + "元");
				}
			}
			}
			}
				
			
				
			public class Test {
			public static void main(String[] args) {
			/*
				微信中的抢红包也用到了多线程。
				假设:100块,分成了3个包,现在有5个人去抢。
				其中,红包是共享数据。
				5个人是5条线程。
				打印结果如下:
					XXX抢到了XXX元
					XXX抢到了XXX元
					XXX抢到了XXX元
					XXX没抢到
					XXX没抢到
			*/


			MyThread t1 = new MyThread();
			MyThread t2 = new MyThread();
			MyThread t3 = new MyThread();
			MyThread t4 = new MyThread();
			MyThread t5 = new MyThread();

			t1.setName("小A");
			t2.setName("小QQ");
			t3.setName("小哈哈");
			t4.setName("小诗诗");
			t5.setName("小丹丹");

			t1.start();
			t2.start();
			t3.start();
			t4.start();
			t5.start();


			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class MyThread extends Thread {

				ArrayList list;

				public MyThread(ArrayList list) {
					this.list = list;
				}

				@Override
				public void run() {
			//1.循环
			//2.同步代码块
			//3.判断
			//4.判断

			while (true) {
				synchronized (MyThread.class) {
					if (list.size() == 0) {
						break;
					} else {
						//继续抽奖
						Collections.shuffle(list);
						int prize = list.remove(0);
						System.out.println(getName() + "又产生了一个" + prize + "元大奖");
					}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class Test {
				public static void main(String[] args) {
					/*
				有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
				创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
				随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
								 每次抽出一个奖项就打印一个(随机)
					抽奖箱1 又产生了一个 10 元大奖
					抽奖箱1 又产生了一个 100 元大奖
					抽奖箱1 又产生了一个 200 元大奖
					抽奖箱1 又产生了一个 800 元大奖
					抽奖箱2 又产生了一个 700 元大奖
					.....
			*/


			//创建奖池
			ArrayList list = new ArrayList<>();
			Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

			//创建线程
			MyThread t1 = new MyThread(list);
			MyThread t2 = new MyThread(list);

			//设置名字
			t1.setName("抽奖箱1");
			t2.setName("抽奖箱2");

			//启动线程
			t1.start();
			t2.start();

			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class MyThread extends Thread {

				ArrayList list;

				public MyThread(ArrayList list) {
					this.list = list;
				}

			//线程一
			static ArrayList list1 = new ArrayList<>();
			//线程二
			static ArrayList list2 = new ArrayList<>();

			@Override
			public void run() {
			while (true) {
				synchronized (MyThread.class) {
					if (list.size() == 0) {
						if("抽奖箱1".equals(getName())){
							System.out.println("抽奖箱1" + list1);
						}else {
							System.out.println("抽奖箱2" + list2);
						}
						break;
					} else {
						//继续抽奖
						Collections.shuffle(list);
						int prize = list.remove(0);
						if("抽奖箱1".equals(getName())){
							list1.add(prize);
						}else {
							list2.add(prize);
						}
					}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class Test {
				public static void main(String[] args) {
					/*
				有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
				创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
				随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
				每次抽的过程中,不打印,抽完时一次性打印(随机)    在此次抽奖过程中,抽奖箱1总共产生了6个奖项。
					分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
				在此次抽奖过程中,抽奖箱2总共产生了6个奖项。
					分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元
			*/

			//创建奖池
			ArrayList list = new ArrayList<>();
			Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

			//创建线程
			MyThread t1 = new MyThread(list);
			MyThread t2 = new MyThread(list);

			//设置名字
			t1.setName("抽奖箱1");
			t2.setName("抽奖箱2");

			//启动线程
			t1.start();
			t2.start();
			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class MyThread extends Thread {

				ArrayList list;

				public MyThread(ArrayList list) {
					this.list = list;
				}

				@Override
				public void run() {
					ArrayList boxList = new ArrayList<>();//1 //2
					while (true) {
				synchronized (MyThread.class) {
					if (list.size() == 0) {
						System.out.println(getName() + boxList);
						break;
					} else {
						//继续抽奖
						Collections.shuffle(list);
						int prize = list.remove(0);
						boxList.add(prize);
					}
				}
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

			}
			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;

			public class Test {
				public static void main(String[] args) {
					/*
				有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
				创建两个抽奖箱(线程)设置线程名称分别为“抽奖箱1”,“抽奖箱2”
				随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:
				每次抽的过程中,不打印,抽完时一次性打印(随机)    在此次抽奖过程中,抽奖箱1总共产生了6个奖项。
					分别为:10,20,100,500,2,300最高奖项为300元,总计额为932元
				在此次抽奖过程中,抽奖箱2总共产生了6个奖项。
					分别为:5,50,200,800,80,700最高奖项为800元,总计额为1835元
			*/

			//创建奖池
			ArrayList list = new ArrayList<>();
			Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

			//创建线程
			MyThread t1 = new MyThread(list);
			MyThread t2 = new MyThread(list);


			//设置名字
			t1.setName("抽奖箱1");
			t2.setName("抽奖箱2");


			//启动线程
			t1.start();
			t2.start();

			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;
			import java.util.concurrent.Callable;

			public class MyCallable implements Callable {

				ArrayList list;

				public MyCallable(ArrayList list) {
					this.list = list;
				}

				@Override
				public Integer call() throws Exception {
				ArrayList boxList = new ArrayList<>();//1 //2
				while (true) {
				synchronized (MyCallable.class) {
					if (list.size() == 0) {
						System.out.println(Thread.currentThread().getName() + boxList);
						break;
					} else {
						//继续抽奖
						Collections.shuffle(list);
						int prize = list.remove(0);
						boxList.add(prize);
					}
				}
				Thread.sleep(10);
			}
			//把集合中的最大值返回
			if(boxList.size() == 0){
				return null;
			}else{
				return Collections.max(boxList);
			}
			}
			}
				
			
				
			import java.util.ArrayList;
			import java.util.Collections;
			import java.util.concurrent.ExecutionException;
			import java.util.concurrent.FutureTask;

			public class Test {
				public static void main(String[] args) throws ExecutionException, InterruptedException {
					/*
				有一个抽奖池,该抽奖池中存放了奖励的金额,该抽奖池中的奖项为 {10,5,20,50,100,200,500,800,2,80,300,700};
				创建两个抽奖箱(线程)设置线程名称分别为    "抽奖箱1", "抽奖箱2"
				随机从抽奖池中获取奖项元素并打印在控制台上,格式如下:

				在此次抽奖过程中,抽奖箱1总共产生了6个奖项,分别为:10,20,100,500,2,300
					最高奖项为300元,总计额为932元

				在此次抽奖过程中,抽奖箱2总共产生了6个奖项,分别为:5,50,200,800,80,700
					最高奖项为800元,总计额为1835元

				在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元
				核心逻辑:获取线程抽奖的最大值(看成是线程运行的结果)


				以上打印效果只是数据模拟,实际代码运行的效果会有差异
			*/

			//创建奖池
			ArrayList list = new ArrayList<>();
			Collections.addAll(list,10,5,20,50,100,200,500,800,2,80,300,700);

			//创建多线程要运行的参数对象
			MyCallable mc = new MyCallable(list);

			//创建多线程运行结果的管理者对象
			//线程一
			FutureTask ft1 = new FutureTask<>(mc);
			//线程二
			FutureTask ft2 = new FutureTask<>(mc);

			//创建线程对象
			Thread t1 = new Thread(ft1);
			Thread t2 = new Thread(ft2);

			//设置名字
			t1.setName("抽奖箱1");
			t2.setName("抽奖箱2");

			//开启线程
			t1.start();
			t2.start();


			Integer max1 = ft1.get();
			Integer max2 = ft2.get();

			System.out.println(max1);
			System.out.println(max2);

			//在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为800元
			if(max1 == null){
				System.out.println("在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为"+max2+"元");
			}else if(max2 == null){
				System.out.println("在此次抽奖过程中,抽奖箱1中产生了最大奖项,该奖项金额为"+max1+"元");
			}else if(max1 > max2){
				System.out.println("在此次抽奖过程中,抽奖箱1中产生了最大奖项,该奖项金额为"+max1+"元");
			}else if(max1 < max2){
				System.out.println("在此次抽奖过程中,抽奖箱2中产生了最大奖项,该奖项金额为"+max2+"元");
			}else{
				System.out.println("两者的最大奖项是一样的");
			}
			}
			}
				
			
单词