65.【 多线程2】(一)

简介: 65.【 多线程2】

(一)、线程的基础

1. 什么是进程?

正在运行中的应用程序QQ,通常称为进程。每个进程都有自己独立的地址空间(内存空间),每当用户启动一个进程时,操作系统就会为该进程分配一个独立的内存空间,让应用程序在这个独立的内存空间中运行。

2.什么是线程?

线程是一个轻量级的子进程,是最小的处理单元;是一个单独的执行路径。可以说:线程是进程的子集(部分)。

3.线程特点:

线程是独立的。如果在一个线程中发生异常,则不会影响其他线程。它使用共享内存区域。

4.进程和线程的区别:

1、容易创建新线程。但是,创建新进程需要重复父进程

2线程可以控制同一进程的其他线程**。进程无法控制兄弟进程,只能控制其子进程。

3、进程拥有自己的内存空间。线程使用进程的内存空间,且要和该进程的其他线程共享这个空间;而不是在进程中给每个线程单独划分一点空间。

4、(同一进程中的)线程在共享内存空间中运行,而进程在不同的内存空间中运行。

5、线程可以使用wait(),notify(),notifyAll()等方法直接与其他线程(同一进程)通信;而,进程需要使用“进程间通信”(IPC)来与操作系统中的其他进程通信。

5.多线程和线程:

多线程是指在系统中同时运行多个线程,如果只有一个处理器只有一个进程的一个指令被执行,可以使这些线程进行交替执行,由于间隔的时间短,这些程序看上去好像在同时运行.

如果将进程划分为线程,每个线程轮流占用处理器,可以减少并发时间.

6.线程、进程、多线程总结

(1).线程就是独立的执行路径;
(每个线程的路都有自己的路要走)
(2).在程序运行时,即使没有自己创建线程,后台也会有多个线程,如主线程,
gc线程
(3).main()称之为主线程,为系统的入口,用于执行整个程序。
(4).在一个进程中,如果开辟了多个线程,线程的运行由调度器(CPU)安排调度,
调度器是与操作系统紧密相关的,先后顺序是不能人为的干预的。
(5).对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制;
(6).线程会带来额外的开销,如cpu调度时间,并发控制开销。
(7).每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

(二)、线程创建 (3种)

7.Thread (线程创建)

基本方法:
1.首先要继承一个Thread
2.要重写run()方法
3.利用类调用start()开启线程

7.1Thread(获取url操作)

1.导入 commons jar包
2.调用commos jar包的copyurltofile 方法是下载指定路径的操作
 FileUtils .copyURLToFile(new URL(url),new File(name));
 3.设置多线程
import org.apache.commons.io.FileUtils;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
import java.io.File;
import java.net.URL;
public class Demo1 extends Thread {
    private String url;
    private String name;
    private Demo1(String url, String name){
        this.name=name;
        this.url=url;
    }
    @Override
    public void run()  {
        WebDownloader webDownloader=new WebDownloader();
        try {
            webDownloader.downloader(url,name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("下载名为:"+name);
    }
    //1.练习Thread,实现多线程同步下载图片
    public static void main(String[] args) {
    Demo1 demo1=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","1.jpg");
    Demo1 demo1_two=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","2.jpg");
    Demo1 demo1_three=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","3.jpg");
    demo1.start();
   demo1_two.start();
   demo1_three.start();
    }
}
//1.下载器
class WebDownloader{
    //下载方法
    public void downloader(String url,String name) throws Exception{
        FileUtils .copyURLToFile(new URL(url),new File(name));
    }
}

8.Runnable (线程创建)

1.创建一个接口 Runnable
2.创建run()接口
3.在实现类创建一个接口类的对象
4.把接口类的对象放进Thread中
5.开启start()方法
public class Demo3 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println("run"+i);
        }
    }
    public static void main(String[] args) {
        for (int i = 0; i <10 ; i++) {
            System.out.println("main"+i);
        }
        //创建Runnable接口类的对象
        Demo3 demo3=new Demo3();
        //把类对象放进Thread中区
//        Thread thread=new Thread(demo3);
//        thread.start();
        new Thread(new Demo3()).start();
    }
}

9.Callable (线程创建)

1.实现callable 接口,需要返回值类型
2.重写call方法,需要抛出异常
3.创建执行服务
ExecutorService executorService= Executors.newFixedThreadPool(1);
4.提交执行:
 Future<Boolean> future=executorService.submit(demo5);
5.获取结果
 boolean b=future.get();
6.关闭服务
executorService.shutdown();
9.1基本语法
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo5 implements Callable<Boolean> {
    @Override
    public Boolean call() {
        for (int i = 0; i <=1000 ; i++) {
            System.out.println("call "+i +"次");
        }
        return true;
    }
    public static void main(String[] args) throws Exception{
        for (int i = 0; i <=1000 ; i++) {
            System.out.println("main"+" "+i);
        }
        Demo5 demo5=new Demo5();
       //创建执行服务
        ExecutorService executorService= Executors.newFixedThreadPool(1);
        //提交执行:
        Future<Boolean> future=executorService.submit(demo5);
        //获取结果
        boolean b=future.get();
        //关闭服务
        executorService.shutdown();
        System.out.println(b);
    }
}
9.2Callable(获取url)
import org.apache.commons.io.FileUtils;
import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;
import java.io.File;
import java.net.URL;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Demo1 implements Callable<Boolean> {
    private String url;
    private String name;
    private Demo1(String url, String name){
        this.name=name;
        this.url=url;
    }
    //1.练习Thread,实现多线程同步下载图片
    public static void main(String[] args) throws Exception{
    Demo1 demo1=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","1.jpg");
    Demo1 demo1_two=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","2.jpg");
    Demo1 demo1_three=new Demo1("https://msn-img-nos.yiyouliao.com/inforec-20221017-3b8adaf89d13eeaa1cb14bc45a596b2c.jpg?time=1666081928&signature=6771DA1973B532ECD0B6BFB9B7666680","3.jpg");
        //创建执行服务
        ExecutorService executorService= Executors.newFixedThreadPool(3);
        //提交执行:
        Future<Boolean> future=executorService.submit(demo1);
        Future<Boolean> future_one=executorService.submit(demo1_two);
        Future<Boolean> future_two=executorService.submit(demo1_three);
        //获取结果
        boolean b1=future.get();
        boolean b2=future_one.get();
        boolean b3=future_two.get();
        //关闭服务
        executorService.shutdown();
    }
    @Override
    public Boolean call() throws Exception {
        WebDownloader webDownloader=new WebDownloader();
        try {
            webDownloader.downloader(url,name);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("下载名为:"+name);
        return true;
    }
}
//1.下载器
class WebDownloader{
    //下载方法
    public void downloader(String url,String name) throws Exception{
        FileUtils .copyURLToFile(new URL(url),new File(name));
    }
}

10.初识并发的问题

当多个线程,同时操作一个资源的时候,会出现数据紊乱
eg: 数量增加,抢同一张票
public class Demo4 implements Runnable{
    private int ticket;
    public Demo4(){ticket=10;}
    @Override
    public void run() {
        while (true){
            if (ticket<=0){
                break;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了-----"+ticket--+"张票");
        }
    }
    public static void main(String[] args) {
        Demo4 demo4=new Demo4();
        new Thread(demo4,"小明").start();
        new Thread(demo4,"老师").start();
        new Thread(demo4,"黄牛").start();
    }
}

11.模拟龟兔赛跑(利用线程)

需求文档:
1.设置一个共同的赛道   (线程)
2.判断比赛是否结束      (是否到达一百步)
3.打印胜利者
4.龟兔赛跑开始
5.故事中是乌龟赢,兔子需要睡觉
6.终于,乌龟赢得了比赛
Thread.currentThread().getName()    获取当前的名字
public class Race implements Runnable{
    private String Vector;
    @Override
    public void run() {
        for (int i = 0; i <=100; i++) {
            //模拟兔子休息
            if (Thread.currentThread().getName().equals("兔子")&&i%10==0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag=gameOver(i);
            if(flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"----跑了 "+i+" 跑了多少步");
        }
    }
    //判断是否成功
    private boolean gameOver(int step){
        if(Vector!=null){
            return true;
        } else {   //
            if(step>=100){
                Vector=Thread.currentThread().getName();
                System.out.println("成功的是:"+Vector);
                return true;
            }
        }
        return false;
    }
    public static void main(String[] args) {
        Race race=new Race();
        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}
public class Demo2 implements Runnable{
    String Vector;
    @Override
    public void run() {
        //利用标志符号进行暂停线程
        for (int i = 0; i <=100; i++) {
            //当兔子走的步数等于50的时候,并且当走的是兔子的时候
            if(i==50&&Thread.currentThread().getName().equals("兔子")){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"走了 "+i);
            //得出胜利者并且结束循环的操作
            if(!stop(i)){
                break;
            }
        }
        }
        //判断是否成功的方法
        public boolean stop(int i){
        if (Vector!=null){
            return false;
        }else {
            if (i>=100){
                Vector=Thread.currentThread().getName();
                System.out.println("成功的是:"+Vector);
                return false;
            }
            }
            return true;
        }
    public static void main(String[] args) {
        Demo2 demo2=new Demo2();
        Thread thread=new Thread(demo2,"兔子");
        Thread thread1=new Thread(demo2,"乌龟");
        thread.start();
        thread1.start();
    }
}


相关文章
|
消息中间件 前端开发
C++11多线程相关
C++11多线程相关
83 0
|
安全 Java
多线程02
多线程02
|
7月前
|
安全 Java C++
多线程问题(四)
多线程问题(四)
42 0
|
7月前
|
安全 Java C#
C#多线程详解
C#多线程详解
68 0
|
7月前
|
缓存 安全 Java
多线程05
多线程05
32 0
|
安全 Linux C++
C++多线程
C++多线程
57 1
|
调度 C++
多线程
多线程
|
API
多线程具体实现(下)
多线程具体实现
51 0
|
存储 缓存 算法
多线程2
多线程2https://www.nowcoder.com/issue/tutorial?tutorialId=94&uuid=b40a485f92ff496b9fe332079fa5be66
74 0
|
存储 安全 Java
多线程1
多线程1-https://www.nowcoder.com/issue/tutorial?tutorialId=94&uuid=4e79fb9392af4f90b898311e8c1efe36
66 0