多线程详解

本文深入探讨了Java中的多线程概念,包括线程的创建(通过Thread类、Runnable接口和Callable接口)、线程状态、线程同步(如synchronized和Lock)、线程池的使用,以及线程通信与协作。同时,强调了lamda表达式在简化代码中的作用,指出了线程管理和控制的重要性,如线程礼让、停止线程和线程休眠等。
摘要由CSDN通过智能技术生成

本章核心概念

◆线程就是独立的执行路径;

◆在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,gc线程;

◆main()称之为主线程,为系统的入口,用于执行整个程序;

◆在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为的干预。

◆对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;

◆线程会带来额外的开销,如cpu调度时间,并发控制开销。

◆每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

多线程的创建

分为三种创建方法

一.Thread class----------》继承了Thread类(重点)
package com.meng.demo01;
//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
//总结:注意,线程开启不一定立即执行,由CPU调度执行
public class TestThread1 extends Thread{
   
    @Override
    public void run() {
   
        //run方法线程体
        for (int i = 0; i < 20; i++) {
   
            System.out.println("我在吃饭---"+i);
        }
    }

    public static void main(String[] args) {
   
        //main主线程
        //创建一个线程对象
        TestThread1 testThread1 = new TestThread1();
        //调用start()方法
        testThread1.start();//start两者交替执行
        //调用run()方法
        //testThread1.run();//先执行run()再执行下一个
        for (int i = 0; i < 20; i++) {
   
            System.out.println("我在看电视---"+i);
        }
    }
}

下载网络图片

package com.meng.demo01;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

//练习Thread,实现多线程同步下载图片
public class TestThread2 extends Thread{
   
    private String url;//网络图片地址
    private String name;//保存文件名

    public TestThread2(String url,String name){
   
        this.name = name;
        this.url =url;
    }
    //下载图片线程的执行体
    @Override
    public void run() {
   
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载的文件名为:"+name);
    }

    public static void main(String[] args) {
   
        TestThread2 testThread2 = new TestThread2("https://profile.csdnimg.cn/1/9/F/1_qq_45343541","mm.jpg");
        testThread2.start();
}

//下载器
class WebDownloader{
   
    //下载方法
    public void downloader(String url,String name) {
   
        try {
   
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {
   
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现问题");
        }
    }
    }
}
二.Runnable接口-----------------》实现Runnable接口(重点)
package com.meng.demo01;
//创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start
public class TestThread3 implements Runnable{
   
    @Override
    public void run() {
   
        //run方法线程体
        for (int i = 0; i < 20; i++) {
   
            System.out.println("我在吃饭---"+i);
        }
    }

    public static void main(String[] args) {
   
        //创建runnbale接口的实现类对象
        TestThread3 testThread3 = new TestThread3();
        //创建线程对象通过线程对象来开启我们的线程代理
        Thread thread = new Thread(testThread3);
        thread.start();
        for (int i = 0; i < 20; i++) {
   
            System.out.println("我在看电视---"+i);
        }
    }
}

火车买票

package com.meng.demo01;
//多个线程同时操作一个对象
//买火车票的例子
//发现问题:多个线程操作同一个自愿的情况下,线程不安全,数据紊乱
public class TestThread4 implements Runnable{
   
    //票数
    private int tickeNums = 10;
    

    @Override
    public void run() {
   
        while (true){
   
            if (tickeNums<=0){
   
                break;
            }
            //模拟延时
            try {
   
                Thread.sleep(200);
            } catch (InterruptedException e) {
   
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"--》拿到了第"+tickeNums--+"票");

        }
    }

    public static void main(String[] args) {
   
        TestThread4 ticket = new TestThread4();
        new Thread(ticket,"杰克").start();
        new Thread(ticket,"斯派克").start();
        new Thread(ticket,"汤姆").start();
    }
}

龟兔赛跑

package com.meng.demo01;
//龟兔赛跑
public class Race implements Runnable{
   
    //胜利者
    private static String winner;
    @Override
    public void run() {
   
        for (int i = 0; i <= 100; i++) {
   
            //模拟兔子休息
            if (Thread.currentThread().getName().equals("兔子")&& i%10==0){
   
                try {
   
                    Thread.sleep(1);
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag = gameOver(i);
            if (flag){
   
                break;
            }
            System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步‍");
        }
    }
    //判断是否完成比赛
    private boolean gameOver(int steps){
   
        if (winner!=null){
   
            return true;
        }{
   
            if (steps>=100){
   
                winner = Thread.currentThread().getName();
                System.out.println("胜利者是"+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
   
        Race race = new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();

    }
}
三.Callable接口-----------------》实现Callable接口(简单了解即可)

1.实现Callable接口,需要返回值类型

2.重写call方法,需要抛出异常

3.创建项目对象

4.创建执行服务:Executor Servicer ser = Executors.newFixedTreadPool(1);

5.提交执行:Futureresult1 = ser.submit(t1);

6.获取结果:boolean r1 = result1.get();

7.关闭服务:ser.shutdownNow();

package com.meng.demo02;

import com.meng.demo01.TestThread2;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//线程创建方式三:实现callable接口
//callable的好处:1.可以定义返回值2.可以抛出异常
public class TestCallable implements Callable<Boolean> {
   
    private String url;//网络图片地址
    private String name;//保存文件名

    public TestCallable(String url,String name){
   
        this.name = name;
        this.url =url;
    }
    //下载图片线程的执行体
    @Override
    public Boolean call() {
   
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        System.out.println("下载的文件名为:"+name);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
   
        TestCallable testThread2 = new TestCallable("https://profile.csdnimg.cn/1/9/F/1_qq_45343541","mm.jpg");
        //创建执行服务:
        ExecutorService ser = Executors.newFixedThreadPool(1);
        //提交执行:
        Future<Boolean> result1 = ser.submit(testThread2);

        //获取结果:
        boolean r1 = result1.get();
        System.out.println(r1);
        //关闭服务:
        ser.shutdownNow();
    }
}
class WebDownloader{
   
    //下载方法
    public void downloader(String url,String name) {
   
        try {
   
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } 
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值