栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

理解多线程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

理解多线程

多线程
  • 多线程
    • 基本概念
    • Thread类
      • 基本使用
      • 基本方法
    • Runnable接口
      • 基本使用
      • 比较创建线程两种方式
    • Callable接口(jdk 5.0以后)
      • 基本使用
      • 如何理解Callable接口比Runnable接口强大?
    • 线程池(jdk 5.0以后)
      • 基本使用
      • 简单介绍
      • 工作流程
      • 好处
    • 线程同步
      • 基本使用
      • 优缺点
      • synchronized与lock的对比
    • 线程通信
      • 生产者消费者问题
    • 线程生命周期

多线程 基本概念

进程:是程序的一次执行过程。进程作为资源的分配单位,系统在运行时会给每个进程分配不同的内存区域。
线程:是程序内部的一条执行路径。线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器。
并行:多个cpu同时执行多个任务
并发:一个cpu同时执行多个任务

Thread类 基本使用
class Threadone extends Thread{
    @Override
    public void run() {
        for(int i=0;i<=100;i++){
            if(i%2==0){
                System.out.println("偶数:"+i);
            }
        }
    }
}
class Threadtwo extends Thread{
    @Override
    public void run() {
        for(int i=0;i<=100;i++){
            if(i%2!=0){
                System.out.println("奇数:"+i);
            }
        }
    }
}
public class MyThread {
    public static void main(String[] args) {
        Threadone threadone=new Threadone();
        Threadtwo threadtwo=new Threadtwo();
        threadone.start();
        threadtwo.start();
    }
}

注意:
1.不能直接调用run()方法启动线程,会使多线程变成单线程。
2.不能让已经start()的线程再执行,不能让进程从死亡状态返回。

基本方法

start():启动当前线程,调用run()方法。
run():将执行操作声明在此方法中。
currentThread():返回当前执行代码的线程。
getName():获取当前线程名字。
setName():设置当前线程名字。
yield():释放当前cpu执行权。
join():在线程a中调用线程b中的join()。
sleep():让当前线程睡眠指定时间。
getPriority():获取线程优先级。
setPriprity():设置线程优先级。
说明: 只是从概率上讲高优先级高概率获得CPU执行权,并不是一定获得执行权

Runnable接口 基本使用
class Product implements Runnable {

    private Goods goods;

    public Product(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true){
            goods.ProductGoods();
        }

    }
}
class Consumers implements Runnable{
    private Goods goods;

    public Consumers(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true){
            goods.ComsumerGoods();
        }

    }
}
public class ProductComsumer {
    public static void main(String[] args) {
        Goods goods=new Goods();
        Product product=new Product(goods);
        Consumers comsumer=new Consumers(goods);
        Thread thread01=new Thread(product);
        Thread thread02=new Thread(comsumer);
        thread01.start();
        thread02.start();
    }


}

比较创建线程两种方式

开发中,优先实现Runnable接口实现方式
原因:
1.实现方式没有类的单继承的局限性。
2.实现方式更适合处理多个线程有共享数据的情况

Callable接口(jdk 5.0以后) 基本使用
class Test implements Callable {

    private int sum=0;
    @Override
    public Integer call() throws Exception {
        for (int i=0;i<=100;i++){
            System.out.println(i);
            sum+=i;
        }
        return sum;
    }
}
public class ThreadCallable {
    public static void main(String[] args) {
        Test test=new Test();
        FutureTask integerFutureTask = new FutureTask<>(test);
        Thread thread=new Thread(integerFutureTask);
        thread.start();
        try {
            Integer sum=integerFutureTask.get();
            System.out.println("总和为:"+sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
如何理解Callable接口比Runnable接口强大?

1.call可以有返回值
2.call可以抛出异常,被外面的操作捕获
3.Callable支持泛型

线程池(jdk 5.0以后) 基本使用
class TestThread implements Runnable{

    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
class TestThread01 implements Runnable{

    @Override
    public void run() {
        for (int i=1000;i>100;i--){
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
public class ThreadPool {
    public static void main(String[] args) {
        ExecutorService executorService= Executors.newFixedThreadPool(100);
        TestThread testThread=new TestThread();
        TestThread01 testThread01=new TestThread01();
        executorService.execute(testThread);
        executorService.execute(testThread01);
        executorService.shutdown();
    }
}
简单介绍

核心线程:线程池新建线程的时候,当前线程总数< corePoolSize,新建的线程即为核心线程。
非核心线程:线程池新建线程的时候,当前线程总数< corePoolSize,新建的线程即为核心线程。
核心线程默认情况下会一直存活在线程池中,即使这个核心线程不工作(空闲状态),除非ThreadPoolExecutor 的 allowCoreThreadTimeOut这个属性为true,那么核心线程如果空闲状态下,超过一定时间后就被销毁。

工作流程

1.当前线程数量未达到 corePoolSize,则新建一个线程(核心线程)执行任务
2.当前线程数量达到了 corePoolSize,则将任务移入阻塞队列等待,让空闲线程处理;
3.当阻塞队列已满,新建线程(非核心线程)执行任务
4.当阻塞队列已满,总线程数又达到了 maximumPoolSize,就会按照拒绝策略处理无法执行的任务,比如RejectedExecutionHandler抛出异常。

好处

1.减少了创建新线程的时间。
2.重复利用线程池中线程,不需要每次创建。
3.便于线程管理。

线程同步 基本使用
class MySynchronized implements Runnable {
    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":" + ticket);
                    ticket--;
                } else {
                    System.out.println(Thread.currentThread().getName() + ":无票了");
                    break;
                }
            }
        }
    }
}

public class Synchronized {
    public static void main(String[] args) {
        MySynchronized mySynchronized=new MySynchronized();
        Thread thread1=new Thread(mySynchronized);
        Thread thread2=new Thread(mySynchronized);
        Thread thread3=new Thread(mySynchronized);
        thread1.setName("窗口1");
        thread2.setName("窗口2");
        thread3.setName("窗口3");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}

优缺点

好处:解决了线程的安全问题
缺点:操作同步代码时,只能有一个线程参与,其他线程等待,相当于单线程操作,降低了效率。

synchronized与lock的对比

1.lock锁(显式锁,需要手动关闭和释放),synchronized(隐式锁,自动释放)
2.lock只有代码块锁,synchronized有代码块锁和方法锁
3.使用lock锁,jvm将花费较少时间调度线程,性能更好。

线程通信 生产者消费者问题
class Goods{
    private int count=0;
    public synchronized void ProductGoods()  {
        if(count<20){
            count++;
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产第"+count+"个产品");
            notify();


        }
        else{
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public synchronized void ComsumerGoods(){

        if (count>0){
            System.out.println("消费第"+count+"个产品");
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            count--;
            notify();
        }
        else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Product implements Runnable {

    private Goods goods;

    public Product(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true){
            goods.ProductGoods();
        }

    }
}
class Consumers implements Runnable{
    private Goods goods;

    public Consumers(Goods goods) {
        this.goods = goods;
    }

    @Override
    public void run() {
        while (true){
            goods.ComsumerGoods();
        }

    }
}
public class ProductComsumer {
    public static void main(String[] args) {
        Goods goods=new Goods();
        Product product=new Product(goods);
        Consumers comsumer=new Consumers(goods);
        Thread thread01=new Thread(product);
        Thread thread02=new Thread(comsumer);
        thread01.start();
        thread02.start();
    }


}

线程生命周期

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328884.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号