先上图,有点长,比较碎,有xmind文件......,详细内容均在图片里介绍了,提供了PDF文件
进程是操作系统中正在执行的不同的应用程序,例如:我们可以同时打开Word和记事本
线程是一个应用程序进程中不同的执行路径。进程是不活泼的。进程从来不执行任何东西,它只是线程的容器。线程总是在某个进程环境中创建的,而且它的整个寿命期都在该进程中。
进程是线程的容器。一个进程可以有多个线程,至少有一个线程。而一个线程只能在一个进程的地址空间活动
- //Thread
- public class MyThread extends Thread{
-
- @Override
- public void run(){
- for (int i = 0; i < 10; i++) {
- System.out.println(getName() + "run方法里的函数");
- }
- }
-
-
-
- }
- //创建开启线程
- public abstract class ThreadDemo {
- public static void main(String[] args) {
- // 创建 MyThread 类的实例
- MyThread t1 = new MyThread();
- MyThread t2 = new MyThread();
-
- t1.setName("线程1");
- t2.setName("线程2");
- // 启动线程
- t1.start();
- t2.start();
- }
- }
- //Runnable
- public class MyRunnable implements Runnable {
- @Override
- public void run() {
- //获取当前线程的对象
- Thread thread = Thread.currentThread();
- System.out.println(thread.getName() + "MyRunnable.run方法实列");
- }
- }
-
- //创建开启线程
- public class ThreadDemo {
- public static void main(String[] args) {
- /*
- * 多线程的第二中启动方式:
- * 1.自己定义一个类实现Runnable方法
- * 2.重写里面的run方法
- * 3.创建自己的类的对象
- * 4.创建一个Thread类的对象,并开启线程
- * */
- MyRunnable myRunnable = new MyRunnable();
- Thread thread1 = new Thread(myRunnable);
- Thread thread2 = new Thread(myRunnable);
- thread1.setName("线程1");
- thread2.setName("线程2");
- thread1.start();
- thread2.start();
-
-
- }
- }
-
- //Callable
- public class MyCallable implements Callable
{ - @Override
- public Integer call() throws Exception {
-
- return 100;
- }
- }
- //第三种方式
- public class ThreadDemo {
- public static void main(String[] args) throws ExecutionException, InterruptedException {
- /*
- *多线程的第三种是实现方式
- * 特点:可以获取到多线程运行的结果
- * 1、创建一个类MyCallable实现Callable接口
- * 2、重写call方法(有返回值的,表示多线程运行的结果)
- * 3、创建MyCallable的对象(表示多线程要执行的任务)
- * 4、创建FutureTalk的对象(作用是管理多线程运行的结果)
- * 5、创建Thread类的对象,并启动(表示线程)
- * */
-
- //创建MyCallable的对象(表示多线程要执行的任务)
- MyCallable myCallable = new MyCallable();
- //创建FutureTalk的对象(作用是管理多线程运行的结果
- FutureTask
futureTask = new FutureTask<>(myCallable); - //创建对象
- Thread thread = new Thread(futureTask);
- //启动线程
- thread.start();
- //获取多线程运行的结果
- Integer i = futureTask.get();
- System.out.println(i);
- }
- }
锁是一种同步机制,可以用来协调多个线程的并发访问,以保证对共享资源的安全访问。可以理解为防止一件东西同时被多个人使用。用于保护线程安全的一种机制。
- static int ticket = 0;
-
- @Override
- public void run() {
- while (true) {
- synchronized (MyThread.class) {
- if (method()) break;
- }
- }
-
- }
-
- private synchronized boolean method() {
- if (ticket < 99){
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- ticket++;
- System.out.println(Thread.currentThread().getName() + "正在卖第 " + ticket + "票!");
-
-
- }else{
- return true;
- }
- return false;
- }
- public class MyThread extends Thread {
-
- static int ticket = 100;
-
- static Lock lock = new ReentrantLock();
-
- @Override
- public void run() {
-
- /*
- * Lock实现提供比使用sunchronized方法和语句更广泛的锁定操作
- * lock中提供了获得锁和释放锁的方法
- * void lock():获得锁
- * void unlock():释放锁
- *
- * Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
- * ReentrantLock的构造方法
- *
- * ReentrantLock():创建一个ReentrantLock的实例
- *
- * */
-
- while (true) {
- //同步代码块,lock上锁
- lock.lock();
- if (ticket == 100){
- break;
- }else {
-
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }finally {
- //释放锁
- lock.unlock();
- }
- ticket++;
- System.out.println(Thread.currentThread().getName() + "在卖第" + ticket);
- }
-
- }
-
-
-
- }
- }
详细介绍可看开头的图片
- public class Desk {
-
- /*
- * 控制生产者和消费者的执行
- * */
-
- //是否有面条 0:没有 1:有
- public static int foodFlag = 0;
-
- //总个数
- public static int count =10;
-
- //锁对象
- public static Object lock = new Object();
- }
-
- //消费者
- public class Cook extends Thread {
- /*
- * 消费者
- * */
- @Override
- public void run() {
- while (true) {
- synchronized (Desk.lock){
- if(Desk.count == 0){
- break;
- }else{
- //判断桌子上是否有食物
- //如果有就等待,没有就唤醒
- if(Desk.foodFlag == 1){
- try {
- //等待
- Desk.lock.wait();
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }else{
- System.out.println("厨师做了一碗面条");
- //修改桌子状态
- Desk.foodFlag = 1;
- //唤醒
- Desk.lock.notifyAll();
- }
- }
-
- }
-
- }
- }
- }
- //生产者
- public class Foodie extends Thread {
- /*
- 生产者
- * */
- @Override
- public void run() {
- /*
- * 1.循环
- * 2.同步代码块
- * 3.判断共享数据是否到了末尾(到了末尾)
- * 4.判断共享数据是否到了末尾(没有到达末尾,执行核心逻辑)
- *
- * */
- while (true) {
- synchronized (Desk.lock){
- //先判断桌子上是否有面条
- if(Desk.count == 0){
- break;
- }else{
- if(Desk.foodFlag == 0){
- //如果没有
- try {
- Desk.lock.wait();//让当前线程和锁进行绑定
- } catch (InterruptedException e) {
- throw new RuntimeException(e);
- }
- }else{
- //把吃的总数-1
- Desk.count--;
- //如果有就开吃
- System.out.println(Desk.count + "碗!!!");
- //吃完之后,唤醒厨师继续做
- Desk.lock.notifyAll();
- //修改桌子的状态
- Desk.foodFlag = 0;
- }
-
- }
- }
-
- }
-
- }
- }
- public class ThreadDemo {
- public static void main(String[] args) {
- /*
- * 阻塞队列的继承结构
- * 接口:Iterable
- * Collection
- * Queue
- * BlockingQueue
- * 实现类L:ArrayBlocking : 数组 ,有界
- * LinkedBlockingQueue:底层是链表,无界,但不是真正的无界,最大为int的最大值+
- *
- * */
- ArrayBlockingQueue
queue = new ArrayBlockingQueue<>(1); - Cook cook = new Cook(queue);
- Foodie foodie = new Foodie(queue);
- cook.start();
- foodie.start();
- }
- }
线程池是一种多线程处理形式,处理过程中可以将任务添加到队列中,然后在创建线程后自动启动这些任务。
- public class MyThreadPoolDemo {
- public static void main(String[] args) {
-
- /*
- public static ExecutorService newCachedThreadPool() 创建一个没有上限的线程池
- public static ExecutorService newFixedThreadPool(int nThread) 创建有上限的线程池
- */
- //1.获取线程池对象,池子本身是空的,提交任务的时,池子会创建新的线程对象,
- // 任务执行完毕,线程归回给池子,下回再次提交任务时,不需要创建新的线程,直接复用已有的线程
- ExecutorService pool = Executors.newCachedThreadPool();
- ExecutorService pool1 = Executors.newFixedThreadPool(3);
- //提交任务
- pool.submit(new MyRunnable());
- pool.submit(new MyRunnable());
- //销毁线程池
- pool.shutdown();
- }
- public class ThreadPool {
- public static void main(String[] args) {
- ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
- 3,
- 6,
- 60,
- TimeUnit.SECONDS,
- new ArrayBlockingQueue<>(2),
- Executors.defaultThreadFactory(),
- new ThreadPoolExecutor.AbortPolicy()
- );
- threadPoolExecutor.submit(new MyRunnable());
- }
- }