IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 记录多线程 -> 正文阅读

[系统运维]记录多线程

线程和进程的基本概念

程序:
? ? ? ?用某种语言编写的一段指令的集合,静态代码静态对象
进程:
? ? ? ?是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间
线程:
? ? ? ?是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行 . 一个进程最少有一个线程 ,线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分 成若干个线程
?

并发与并行 &&同步与异步

并发:一个CPU同时执行多个任务

并行:多个CPU同时执行多个不同任务

前者是逻辑上的同时发生,后者是物理上的同时发生

同步:排队执行 , 效率低但是安全。

异步:同时执行 , 效率高但是数据不安全。

线程的调度方式?

分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

抢占式调度:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性)

注意:多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的 使

用率更高。

? ?

?线程的相关API

//获取当前线程的名字
Thread.currentThread().getName()

1.start():1.启动当前线程2.调用线程中的run方法
2.run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中
3.currentThread():静态方法,返回执行当前代码的线程
4.getName():获取当前线程的名字
5.setName():设置当前线程的名字
6.yield():主动释放当前线程的执行权
7.join():在线程中插入执行另一个线程,该线程被阻塞,直到插入执行的线程完全执行完毕以后,该线程才继续执行下去
8.stop():过时方法。当执行此方法时,强制结束当前线程。
9.sleep(long millitime):线程休眠一段时间
10.isAlive():判断当前线程是否存活
?

多线程的创建方式

1.继承Thread

1.创建一个集成于Thread类的子类 (通过ctrl+o(override)输入run查找run方法)
2.重写Thread类的run()方法
3.创建Thread子类的对象
4.通过此对象调用start()方法

创建线程的方式: MyThread myThread = new MyThread();

2.实现Runnable

相比较Thread而言,通过实现runnable的方式可以更容易地实现资源共享,并且接口可以多实现且还能再继承其他类.

面向接口编程, 松耦合设计
不能独立运行, 需绑定在Thread实例上运行
主线程不能监控子线程何时结束, 也不能获取子线程返回结果
切记启动异步线程的方式是调用start()方法, 而非调用run()方法.
主线程不能捕获子线程的抛出的异常, 通常会在run()方法中包裹一个最大的try-catch,自行处理异常

步骤

1.创建一个实现了Runable接口的类
2.实现类去实现Runnable中的抽象方法:run()
3.创建实现类的对象
4.将此对象作为参数传递到Thread类中的构造器中,创建Thread类的对象
5.通过Thread类的对象调用start()

	package com.example.paoduantui.Thread;
	
	public class ThreadDemo01 {
	    
	    public static  void main(String[] args){
	        window1 w = new window1();
	        
	        //虽然有三个线程,但是只有一个窗口类实现的Runnable方法,由于三个线程共用一个window对象,所以自动共用100张票
	        
	        Thread t1=new Thread(w);
	        Thread t2=new Thread(w);
	        Thread t3=new Thread(w);
	
	        t1.setName("窗口1");
	        t2.setName("窗口2");
	        t3.setName("窗口3");
	        
	        t1.start();
	        t2.start();
	        t3.start();
	    }
	}
	
	class window1 implements Runnable{
	    
	    private int ticket = 100;
	
	    @Override
	    public void run() {
	        while(true){
	            if(ticket>0){
	//                try {
	//                    sleep(100);
	//                } catch (InterruptedException e) {
	//                    e.printStackTrace();
	//                }
	                System.out.println(Thread.currentThread().getName()+"当前售出第"+ticket+"张票");
	                ticket--;
	            }else{
	                break;
	            }
	        }
	    }
	}

?3.实现callable接口方式:

Runnable与Callable

接口定义
//Callable 接口
public interface Callable<V> {
V call() throws Exception;
}
//Runnable 接口
public interface Runnable {
public abstract void run();
}

?callable使用步骤

1. 编写类实现 Callable 接口 , 实现 call 方法
class XXX implements Callable<T> {
@Override
? ? ? ? public <T> call() throws Exception {
? ? ? ? ? return T;
? ? ?}
}
2. 创建 FutureTask 对象 , 并传入第一步编写的 Callable 类对象
? ? FutureTask<Integer> future = new FutureTask<>(callable);
3. 通过 Thread, 启动线程
new Thread(future).start();

Runnable与Callable?相同点与不同点


相同:

都是接口

都可以编写多线程程序
都采用 Thread.start() 启动线程
不同:
Runnable 没有返回值; Callable 可以返回执行结果
Callable 接口的 call() 允许抛出异常; Runnable run() 不能抛出
注意:
Callalble 接口支持返回执行结果,需要调用 FutureTask.get() 得到,此方法会阻塞主进程的继续往下执行,如果不调用不会阻塞。

?4.线程池方式

线程池? Executors

如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程 就会大大降低 系统的效率,因为频繁创建线程和销毁线程需要时间. 线程池就是一个容纳多个线程的容 器,池中的线程可以反复使用,省去了频繁创建线程对象的操作,节省了大量的时间和资源。
好处:
降低资源消耗。
提高响应速度。
提高线程的可管理性。

?Java中的四种线程池 . ExecutorService

?缓存线程池:ExecutorService service =Executors.newCachedThreadPool();

?定长线程池:ExecutorService service =Executors.newFixedThreadPool();

?单线程线程池:ExecutorService service =Executors.newSingleThreadExecutor();

?周期性任务定长线程池:

ScheduledExecutorService service =?Executors.newScheduledThreadPool();

线程的生命周期:

?

线程通信的常用方法:

?

?

?线程的安全问题:

线程安全问题是指,多个线程对同一个共享数据进行操作时,线程没来得及更新共享数据,从而导致另外线程没得到最新的数据,从而产生线程安全问题。

?线程安全解决方法:

?方式1:同步代码块:

使用同步监视器(锁)
Synchronized(同步监视器){
//需要被同步的代码
}

方式2:同步方法:?

使用同步方法,对方法进行synchronized关键字修饰
将同步代码块提取出来成为一个方法,用synchronized关键字修饰此方法。
对于runnable接口实现多线程,只需要将同步方法用synchronized修饰
而对于继承自Thread方式,需要将同步方法用static和synchronized修饰,因为对象不唯一(锁不唯一)
?

注意

1.同步方法仍然涉及到同步监视器,只是不需要我们显示的声明。
2.非静态的同步方法,同步监视器是this
静态的同步方法,同步监视器是当前类本身。继承自Thread。class

方式3:显式锁lock:

package com.example.paoduantui.Thread;


import java.util.concurrent.locks.ReentrantLock;

class Window implements Runnable{
    private int ticket = 100;//定义一百张票
    //1.实例化锁
    private ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        
            while (true) {

                //2.调用锁定方法lock
                lock.lock();

                if (ticket > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    System.out.println(Thread.currentThread().getName() + "售出第" + ticket + "张票");
                    ticket--;
                } else {
                    break;
                }
            }


        }
}

public class LockTest {

    public static void main(String[] args){
       Window w= new Window();

       Thread t1 = new Thread(w);
       Thread t2 = new Thread(w);
       Thread t3 = new Thread(w);

       t1.setName("窗口1");
       t2.setName("窗口1");
       t3.setName("窗口1");

       t1.start();
       t2.start();
       t3.start();
    }

}

Synchronized与lock的异同?

相同:二者都可以解决线程安全问题
不同:synchronized机制在执行完相应的代码逻辑以后,自动的释放同步监视器
lock需要手动的启动同步(lock()),同时结束同步也需要手动的实现(unlock())(同时以为着lock的方式更为灵活)

优先使用顺序:
LOCK->同步代码块->同步方法
?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-09-06 11:30:56  更:2021-09-06 11:33:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 14:04:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码