阿里云大学课27. Thread类实现多线程

要想实现多线程必须有一个多线程的执行主类。
主类的定义结构:

  • 继承一个Thread类
  • 【推荐-避免单继局限】实现Runnable、Callable接口

java.lang.Thread 直接继承Thread类并覆写类中的run()方法(相当于线程的主方法)

class MyThread extends Thread {
    //线程主体类
    private String title;
    public MyThread(String title) {
        this.title = title;
    }
    @Override
    public void run() { // 所有的线程从此处开始执行
        for (int x = 0; x < 10; x++) {
            System.out.println(this.title + ", x = " + x);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程A");
        MyThread mt2 = new MyThread("线程B");
        MyThread mt3 = new MyThread("线程C");
        mt1.start(); //错误的启动: mt1.run();
        mt2.start();jichu
        mt3.start(); 
    }
}

java多线程测试main 循环执行 java多线程操作map_多线程

只是顺序打印

正确启动多线程的方式应该调用的是Thread类当中的start()方法

多线程启动只有一个方法:public void start()

java多线程测试main 循环执行 java多线程操作map_java多线程测试main 循环执行_02


java多线程测试main 循环执行 java多线程操作map_java多线程测试main 循环执行_03

java多线程测试main 循环执行 java多线程操作map_List_04

课28. Runnable 接口实现多线程

Runnable里只有一个run()方法, 和Thread相同,

@FunctionalInterface
public interface Runnable {
    public void run();
}

//利用Runnable 定义线程主体类
class MyThread implements Runnable {
    //线程主体类
    private String title;
    public MyThread(String title) {
        this.title = title;
    }
    @Override
    public void run() { // 所有的线程从此处开始执行
        for (int x = 0; x < 10; x++) {
            System.out.println(this.title + ", x = " + x);
        }
    }
}

public class Demo {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread("线程A");
        MyThread mt2 = new MyThread("线程B");
        MyThread mt3 = new MyThread("线程C");
        new Thread(mt1).start(); //匿名内部类传入一个接口
        new Thread(mt2).start();
        new Thread(mt3).start();
    }
}

Thread与Runnable的区别
public class Thread extends Object implement Runnable 实现Runnable方法会导致没法调用Thread类中的start()方法,稍微拐个弯用Thread的构造方法public Thread(Runnable target)来接收Runnable接口对象,然后再直接调用start()方法

课29 Thread与Runnable的区别

Runnable避免了单继承局限,
Thread类的继承定义形式
public class Thread extends Object implements Runnable Thread是Runnable接口的子类

@Override
public run() {
    if (target != null) {

线程池:多个线层封装在一起进行操作
为什么需要线程池?
例子:兄弟们,有个活,3天完成,20个人一起干 20个人就是一个线程池

java.util.concurrent从JDK 1.5之后的添加的并发数据包

Interface ExecutorService
Interface ScheduledExecutorService
如果要进行线程池的创建

创建无限大小 线程对象
创建固定大小的线程池
创建定时调度池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo {
    public static void main(String[] args) throws Exception {
        //创建一个线程池的模型
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); 
        for (int x = 0; x < 10; x++) {
            executorService.submit(() -> {
               System.out.println(Thread.currentThread().getName() + "、 x = " + index);
                });
        }
        executorService.shutdown(); 

使用Object类当中的唤醒与等待机制进行操作
public final void notify() //唤醒第一个等待线程

public final void notifyAll() //


```java
class Data {
    private String title;
    private note;

    private boolean flag = true;

    public synchronized void set(String title, String note) {
        if (this.flag = false) {
            try {
                super.

请解释sleep() 与 wait()的区别
*sleep() 是Thread类中定义的方法,到了一定的时间后该休眠的线程可以自动唤醒
*wait() 是Object类中定义的方法,如果想要唤醒,必须使用notify()、notifyAll() 才能唤醒

Java的类集之中(java.util包) 当中提供的两个最为重要核心的操作接口: Collection + Map

Collection 与链表类似:每一次进行数据操作的时候只能够对单个的对象进行处理,所以Collection是单个集合保存的最大父接口

Collection接口的定义

public interface <E> extends Iterable<E>

最重要的几个方法:
子接口都有的两个方法
* public boolean add(E)
* public Iterator iterator 取得Iterator

考虑Collection接口的子接口: List(允许重复) Set(不允许重复)

java多线程测试main 循环执行 java多线程操作map_多线程_05

List接口

两个重要的扩充方法:
* public E get(int index) //根据索引取得数据 * public E set(int index, E element) //修改数据 List使用比例可以达到Collection的 80%
线程的同步和死锁,概念很重要

List三个常用子类:ArrayList, Vector, LinkedList

所有子类的方法都可以参考接口中的定义,使用形式上相同

java多线程测试main 循环执行 java多线程操作map_java_06

对比区别:
ArrayList: 一个针对于List接口的数组操作实现
每一个线程对象操作的延迟问题(轮番抢占资源导致)
先做一个简单的程序:实现多个线程卖票的处理

//source: aliyun java学习路线图-高级【课时35】
class MyThread implements Runnable {
    private int ticket = 10; //要卖出的总票数
    
    @Override
    public void run() {
        for (int x = 0; x < 20; x++) {
            if (this.ticket > 0) {
                try
                System.out.println(Thread.currentThread().getName() + "卖票, ticket = " + this.ticket;
            }
        }
    }

    public class Demo {
        public static void main(String[] args) throws Exception {
            System.out.println(Thread.currentThread().getPriority());
        }
    }
}

Set接口集合

TreeSet排序分析

使用TreeSet排序,需要Comparable类的支持,所有属性都需要参与比较

import java.util.LinkedList;
class Person {
    private String

List
AbstractSet -中间的抽象类
HashSet:无序存储
TreeSet: 有序存储

Hash算法

如何解决
1.同步代码块:

  • 在方法里面进行拦截,用同步代码块必须要设置一个锁定的对象

HashTable

HashMap
请解释HashMap的原理

请解释HashMap与HashTable的区别

Concurrent HashMap

区别

HashMap

HashTable

推出版本

JDK 1.2推出

JDK 1.0推出

性能

异步处理、性能高

同步处理、性能较低

安全性

非线程安全

线程安全

null操作

允许存放null

key 和 value都不允许为空,否则会出现NullPointerException

多考虑HashMap

不是传统的软件开发而是互联网的项目了