多线程基础

线程创建

继承Thread类

public class TestThread1 extends Thread{
    @Override
    public void run() {
        // run 方法线程体
        System.out.println("我在看视频");
    }
    public static void main(String[] args) {
        // main 主线程体
        // 创建一个线程对象
        TestThread1 testThread1 = new TestThread1();
        // 调用start()方法开启线程
        testThread1.start();
    }
}

 

实现Runnable接口

public class TestThread2 implements Runnable {
    @Override
    public void run() {
        System.out.println("我在学习");
    }
    public static void main(String[] args) {
        TestThread2 testThread2 = new TestThread2();

        // 开启子线程 (这里采用代理模式)
        new Thread(testThread2).start();
    }
}

 

实现Callable接口(了解)

public class TestThread3 implements Callable<Integer> {
    // 这里需要返回类型
    @Override
    public Integer call() throws Exception {
        System.out.println("法外狂徒张三在作案");
        return 100;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask<Integer>(new TestThread3());
        new Thread(futureTask).start();
        Integer integer = futureTask.get(); // 这里获取返回值
        System.out.println(integer);
    }
}

 

线程状态

查看线程的状态通过getState()方法。

 

线程休眠

Thread.sleep(1000); // 单位是毫秒
  • sleep指定当前线程阻塞的毫秒数
  • sleep时间到达后线程进入就绪状态
  • 每一个对象都有一个锁,sleep不会释放锁

 

线程礼让

Thread.yield();  // 礼让
  • 礼让线程,让当前正在执行的线程暂停,但不阻塞
  • 将线程从运行状态转为就绪状态
  • 礼让是让cpu重新调度,所以礼让不一定成功!

 

线程插入

public static void main(String[] args) throws InterruptedException {
        // 自定义线程
        Thread t = new Thread(()-> {
            for (int i = 0; i < 10; i++) {
                System.out.println("我来插入执行");
            }
        });

        // 主线程
        for (int i = 0; i < 20; i++) {
            if (i == 10) {
                t.join(); // 强制插入t线程,待t线程执行完,再继续执行main线程
            }
            System.out.println("我是主线程");
        }
    }

 

线程优先级

  • 线程调度器按照优先级决定应该调度哪个线程来执行
  • 线程的优先级用数字表示,范围从1~10
  • getPriority() 获取优先级
  • setPriority(int xx) 设置优先级
  • 注意:若设置优先级,一定先设置优先级,后启动

 

守护线程

  • 线程分为用户线程和守护线程
  • 虚拟机必须确保用户线程执行完毕
  • 虚拟机不用等待守护线程执行完毕
  • 通过setDaemon(true)来设置该线程为守护线程

 

锁问题

初步了解多线程在并发问题中,采取的简单措施。

  • synchronized 关键字,锁的是this,用于同步方法,或者代码块
  • 可重入锁Lock,ReentrantLock类实现了Lock,它拥有与synchronized 相同的并发性和内存语义,在实现线程安全的控制中,比较常用的是ReentrantLock,可以显示加锁,释放锁。

 

生产消费者模式

生产消费者模式问题可以有两种解决方法:管道法(用缓冲区)、信号灯法(标识变量)

示例:缓冲区方式

public class TestPC {

    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

// 生产者 线程
class Productor extends Thread{
    SynContainer container;
    public Productor(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                container.product(new Chicken(i));
                System.out.println("生产-->" + i/10 + "-" + i%10 + "只鸡");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 消费者 线程
class Consumer extends Thread {
    SynContainer container;
    public Consumer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            try {
                Chicken chicken = container.pop();
                System.out.println("消费了-->" + chicken.getId()/10 + "-" + chicken.getId()%10 + "只鸡");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

// 产品
class Chicken {
    int id; // 编号

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Chicken(int id) {
        this.id = id;
    }
}

class SynContainer {
    // 声明缓冲区的数量
    Chicken[] chickens = new Chicken[10];

    // 存在的数量
    int count = 0;

    // 生产一只鸡
    public synchronized void product(Chicken chicken) throws InterruptedException {
        while (count >= 9) {
            this.wait();
        }
        chickens[count++] = chicken;
        this.notifyAll(); // 唤醒消费进程
    }

    // 消费鸡
    public synchronized Chicken pop() throws InterruptedException {
        while (count <= 0) {
            this.wait();
        }
        count--;
        this.notifyAll(); // 唤醒生产者
        return chickens[count];
    }
}

 

posted @ 2020-11-26 17:18  维新派丁真  阅读(103)  评论(0编辑  收藏  举报