前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Lock介绍

Lock介绍

原创
作者头像
HLee
修改于 2021-10-18 01:07:38
修改于 2021-10-18 01:07:38
83300
代码可运行
举报
文章被收录于专栏:房东的猫房东的猫
运行总次数:0
代码可运行

简介

java.util.concurrent.locks包下常用的类与接口(lock是jdk 1.5后新增的)。

锁是用于通过多个线程控制对共享资源的访问的工具,通常锁提供对共享资源的独占访问,一次只能有一个线程可以获取锁,并且对共享资源的所有访问都要求首先获取锁。 但是,一些锁可能允许并发访问共享资源,如ReadWriteLock的读写锁。在Lock接口出现之前,Java程序是靠synchronized关键字实现锁功能的。JDK1.5之后并发包中新增了Lock接口以及相关实现类来实现锁功能。synchronized方法和语句的范围机制使得使用监视器锁更容易编程,并且有助于避免涉及锁的许多常见编程错误,但是有时您需要以更灵活的方式处理锁。

  1. 如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两种情况: 获取锁的线程执行完了该代码块,然后线程释放对锁的占有
  2. 线程执行发生异常,此时JVM会让线程自动释放锁

那么如果这个获取锁的线程由于要等待IO或者其他原因(比如调用sleep方法)被阻塞了,但是又没有释放锁,其他线程便只能地等待,这多么影响程序执行效率。因此就需要有一种机制可以不让等待的线程一直无期限地等待下去(比如只等待一定的时间或者能够响应中断),通过Lock就可以办到。

Lock接口

通过查看Lock的源码可知,Lock是一个接口,接口的实现类ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock。

Lock接口有6个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 获取锁  
void lock()   

// 如果当前线程未被中断,则获取锁,可以响应中断  
void lockInterruptibly()   

// 返回绑定到此 Lock 实例的新 Condition 实例  
Condition newCondition()   

// 仅在调用时锁为空闲状态才获取该锁,可以响应中断  
boolean tryLock()   

// 如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁  
boolean tryLock(long time, TimeUnit unit)   

// 释放锁  
void unlock()  

ReentrantLock类

ReentrantLock意思是“可重入锁”,ReentrantLock是唯一实现了Lock接口的类,并且ReentrantLock提供了更多的方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ReentrantLock() //创建一个 ReentrantLock 的实例
ReentrantLock(boolean fair) //创建一个具有给定公平策略的 ReentrantLock 

int getHoldCount() //查询当前线程保持此锁的次数
protected Thread getOwner() //返回目前拥有此锁的线程,如果此锁不被任何线程拥有,则返回 null 
protected Collection<Thread> getQueuedThreads() //返回一个collection,它包含可能正等待获取此锁的线程 
int getQueueLength() //返回正等待获取此锁的线程估计数 
protected Collection<Thread> getWaitingThreads(Condition condition) //返回一个 collection,它包含可能正在等待与此锁相关给定条件的那些线程 
int getWaitQueueLength(Condition condition) //返回等待与此锁相关的给定条件的线程估计数
boolean hasQueuedThread(Thread thread) //查询给定线程是否正在等待获取此锁
boolean hasQueuedThreads() //查询是否有些线程正在等待获取此锁
boolean hasWaiters(Condition condition) //查询是否有些线程正在等待与此锁有关的给定条件
boolean isFair() //如果此锁的公平设置为 true,则返回true 
boolean isHeldByCurrentThread() //查询当前线程是否保持此锁
boolean isLocked() //查询此锁是否由任意线程保持
void lock() //获取锁
void lockInterruptibly() //如果当前线程未被中断,则获取锁。
Condition newCondition() //返回用来与此 Lock 实例一起使用的 Condition 实例 
boolean tryLock() //仅在调用时锁未被另一个线程保持的情况下,才获取该锁
boolean tryLock(long timeout, TimeUnit unit) //如果锁在给定等待时间内没有被另一个线程保持,且当前线程未被中断,则获取该锁 
void unlock() //试图释放此锁
  • 构造函数:不带参数
  • 构造函数:带参数 
    • true:公平锁;
    • false:非公平锁
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * Creates an instance of {@code ReentrantLock}.
 * This is equivalent to using {@code ReentrantLock(false)}.
 */
public ReentrantLock() {
    sync = new NonfairSync();
}

/**
 * Creates an instance of {@code ReentrantLock} with the
 * given fairness policy.
 *
 * @param fair {@code true} if this lock should use a fair ordering policy
 */
public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}

ReentrantLock和synchronized关键字一样可以用来实现线程之间的同步互斥,功能比synchronized关键字更强大而且更灵活。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LockTest {

    public static void main(String[] args) {
        Lock lock = new ReentrantLock();

        Thread thread = new ThreadUser(lock);
        Thread thread1 = new ThreadUser(lock);
        Thread thread2 = new ThreadUser(lock);

        thread.start();
        thread1.start();
        thread2.start();
    }
}

class ThreadUser extends Thread{

    private Lock lock;

    public ThreadUser(Lock lock) {
        this.lock = lock;
    }

    @Override
    public void run() {
        lock.lock();
        for (int i = 0; i < 3; i++) {
            System.out.println(Thread.currentThread().getName() + ": " + (i + 1));
        }
        lock.unlock();
    }
}

执行结果:
Thread-0: 1
Thread-0: 2
Thread-0: 3
Thread-1: 1
Thread-1: 2
Thread-1: 3
Thread-2: 1
Thread-2: 2
Thread-2: 3

总结一下:

  • synchronized是Java语言的关键字,因此是内置特性,Lock不是Java语言内置的,Lock是一个接口,通过实现类可以实现同步访问。
  • synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中
  • 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock,但是在资源竞争很激烈的情况下,Synchronized的性能会下降几十倍,但是ReetrantLock的性能能维持常态。

Condition接口

synchronized关键字与wait()和notify/notifyAll()方法相结合可以实现等待/通知机制,ReentrantLock类当然也可以实现,但是需要借助于Condition接口与newCondition() 方法。Condition是JDK1.5之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活。

在使用notify/notifyAll()方法进行通知时,被通知的线程是有JVM选择的,使用ReentrantLock类结合Condition实例可以实现“选择性通知”,这个功能非常重要,而且是Condition接口默认提供的。

而synchronized关键字就相当于整个Lock对象中只有一个Condition实例,所有的线程都注册在它一个身上。如果执行notifyAll()方法的话就会通知所有处于等待状态的线程这样会造成很大的效率问题,而Condition实例的signalAll()方法 只会唤醒注册在该Condition实例中的所有等待线程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void await() //造成当前线程在接到信号或被中断之前一直处于等待状态。 
boolean await(long time, TimeUnit unit) //造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。 
long awaitNanos(long nanosTimeout) //造成当前线程在接到信号、被中断或到达指定等待时间之前一直处于等待状态。 
void awaitUninterruptibly() //造成当前线程在接到信号之前一直处于等待状态。 
boolean awaitUntil(Date deadline) //造成当前线程在接到信号、被中断或到达指定最后期限之前一直处于等待状态。 
void signal() //唤醒一个等待线程。 
void signalAll() //唤醒所有等待线程。 

Condition实现等待/通知机制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LockTest2 {

    public static void main(String[] args) throws Exception{
        LockService2 lockService2 = new LockService2();

        Thread thread = new ThreadUser2(lockService2);
        thread.start();

        Thread.sleep(2000);

        lockService2.singal();
    }
}

class ThreadUser2 extends Thread {

    private LockService2 lockService2;

    public ThreadUser2(LockService2 lockService2) {
        this.lockService2 = lockService2;
    }

    @Override
    public void run() {
        lockService2.await();
    }
}

class LockService2{

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void await() {
        try {
            lock.lock();
            System.out.println("await方法开始于: " + System.currentTimeMillis());
            condition.await();
            System.out.println("await方法结束于: " + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void singal() {
        lock.lock();
        System.out.println("singal方法开始于: " + System.currentTimeMillis());
        condition.signal();
        lock.unlock();
    }
}

执行结果:
await方法开始于: 1633782223657
singal方法开始于: 1633782225660
await方法结束于: 1633782225660

在使用wait/notify实现等待通知机制的时候我们知道必须执行完notify()方法所在的synchronized代码块后才释放锁。在这里也差不多,必须执行完signal所在的try语句块之后才释放锁,condition.await()后的语句才能被执行。

多个Condition实例实现等待/通知机制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.java.master.Lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class LockTest3 {

    public static void main(String[] args) throws InterruptedException {

        MyserviceMoreCondition service = new MyserviceMoreCondition();

        ThreadA a = new ThreadA(service);
        a.setName("A");
        a.start();

        ThreadB b = new ThreadB(service);
        b.setName("B");
        b.start();

        Thread.sleep(3000);

        service.signalAll_A();
    }

    static public class ThreadA extends Thread {

        private MyserviceMoreCondition service;

        public ThreadA(MyserviceMoreCondition service) {
            this.service = service;
        }

        @Override
        public void run() {
            service.awaitA();
        }
    }

    static public class ThreadB extends Thread {

        private MyserviceMoreCondition service;

        public ThreadB(MyserviceMoreCondition service) {
            this.service = service;
        }

        @Override
        public void run() {
            service.awaitB();
        }
    }
}

class MyserviceMoreCondition {

    private Lock lock = new ReentrantLock();

    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();

    public void awaitA() {
        lock.lock();
        try {
            System.out.println("begin awaitA时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionA.await();
            System.out.println("end awaitA时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void awaitB() {
        lock.lock();
        try {
            System.out.println("begin awaitB时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionB.await();
            System.out.println("end awaitB时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void signalAll_A() {
        lock.lock();
        try {
            System.out.println("signalAll_A时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionA.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void signalAll_B() {
        lock.lock();
        try {
            System.out.println("signalAll_B时间为" + System.currentTimeMillis()
                    + " ThreadName=" + Thread.currentThread().getName());
            conditionB.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

执行结果:
begin awaitA时间为1633950645627 ThreadName=A
begin awaitB时间为1633950645628 ThreadName=B
signalAll_A时间为1633950648629 ThreadName=main
end awaitA时间为1633950648630 ThreadName=A

Condition实例生产者&消费者

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.java.master.Lock;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author Huan Lee
 * @version 1.0
 * @date 10/11/21 7:14 PM
 * @describtion 业精于勤,荒于嬉;行成于思,毁于随。
 */
public class LockTest4 {

    public static void main(String[] args) {

        LockService4 lockService4 = new LockService4();

        // 一生产者 一消费者
//        Thread producer = new LockProducer4(lockService4);
//        producer.start();
//
//        Thread consumer = new LockConsumer4(lockService4);
//        consumer.start();

        // 多生产者 多消费者
        int size = 2;
        Thread[] producers = new Thread[size];
        Thread[] consumers = new Thread[size];

        for (int i = 0; i < size; i++) {
            char c = (char)('A' + i);

            producers[i] = new LockProducer4(lockService4);
            producers[i].setName("生产者" + c);
            producers[i].start();

            consumers[i] = new LockConsumer4(lockService4);
            consumers[i].setName("消费者" + c);
            consumers[i].start();
        }
    }
}

class LockProducer4 extends Thread{
    private LockService4 lockService4;

    public LockProducer4(LockService4 lockService4) {
        this.lockService4 = lockService4;
    }

    @Override
    public void run() {
        while (true) {
            lockService4.set();
        }
    }
}

class LockConsumer4 extends Thread{
    private LockService4 lockService4;

    public LockConsumer4(LockService4 lockService4) {
        this.lockService4 = lockService4;
    }

    @Override
    public void run() {
        while (true) {
            lockService4.get();
        }
    }
}

class LockService4{

    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private String val = "";

    public void set() {
        try {
            lock.lock();
            while (!"".equals(val)) {
                condition1.await();
            }
            val = System.currentTimeMillis() + "-" + System.nanoTime();
            System.out.println(Thread.currentThread().getName() + " 生产总值: " + val);
//            condition1.signal(); // 一生产者 一消费者
            condition1.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        try {
            lock.lock();
            while ("".equals(val)) {
                condition1.await();
            }
            System.out.println(Thread.currentThread().getName() + " 消费总值: " + val);
            val = "";
//            condition1.signal(); // 一生产者 一消费者
            condition1.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

公平锁与非公平锁

Lock分为公平锁和非公平锁两种,公平锁表示线程获取锁的顺序是按照加锁的顺序来分配的,也就是先到先得;而非公平锁就是一种抢占机制,是随机获取锁,先来的不一定先获取锁。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LockTest5 {

    public static void main(String[] args) {
//        LockService5 lockService5 = new LockService5(true); // 公平锁
        LockService5 lockService5 = new LockService5(false); // 非公平锁

        Thread[] threads = new Thread[5];
        for (int i = 0; i < threads.length; i++) {
            threads[i] = new LockUser5(lockService5);
        }
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
    }
}

class LockUser5 extends Thread{
    private LockService5 lockService5;

    public LockUser5(LockService5 lockService5) {
        this.lockService5 = lockService5;
    }

    @Override
    public void run() {
        lockService5.fool();
    }
}

class LockService5{

    private Lock lock;
    public LockService5(boolean isFair) {
        // 无参是非公平锁  参数 是true是公平锁
        lock = new ReentrantLock(isFair);
    }

    public void fool() {
        try {
            lock.lock();
            System.out.println(Thread.currentThread().getName() + " 获得锁定");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

非公平:
Thread-0 获得锁定
Thread-3 获得锁定
Thread-4 获得锁定
Thread-1 获得锁定
Thread-2 获得锁定

公平:
Thread-0 获得锁定
Thread-1 获得锁定
Thread-2 获得锁定
Thread-3 获得锁定
Thread-4 获得锁定

Condition实现顺序执行

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ConditionSeqExec {

    volatile private static int nextPrintWho = 1;

    // 默认情况下ReentranLock类使用的是非公平锁
    final private static ReentrantLock lock = new ReentrantLock();

    final private static Condition conditionA = lock.newCondition();
    final private static Condition conditionB = lock.newCondition();
    final private static Condition conditionC = lock.newCondition();

    public static void main(String[] args) {


        Thread threadA = new Thread() {
            public void run() {
                lock.lock();
                try {
                    while (nextPrintWho != 1) {
                        conditionA.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadA" + (i + 1));
                    }

                    nextPrintWho = 2;
                    //通知conditionB实例的线程运行
                    conditionB.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadB = new Thread() {
            public void run() {
                lock.lock();
                try {
                    while (nextPrintWho != 2) {
                        conditionB.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadB" + (i + 1));
                    }

                    nextPrintWho = 3;
                    //通知conditionB实例的线程运行
                    conditionC.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread threadC = new Thread() {
            public void run() {
                lock.lock();
                try {
                    while (nextPrintWho != 3) {
                        conditionC.await();
                    }
                    for (int i = 0; i < 3; i++) {
                        System.out.println("ThreadC" + (i + 1));
                    }

                    nextPrintWho = 1;
                    //通知conditionB实例的线程运行
                    conditionA.signalAll();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };

        Thread[] array1 = new Thread[5];
        Thread[] array2 = new Thread[5];
        Thread[] array3 = new Thread[5];

        for (int i = 0; i < 5; i++) {
            array1[i] = new Thread(threadA);
            array2[i] = new Thread(threadB);
            array3[i] = new Thread(threadC);

            array1[i].start();
            array2[i].start();
            array3[i].start();
        }
    }
}

在一个线程运行完之后通过condition.signal()/condition.signalAll()方法通知下一个特定的运行运行,就这样循环往复即可。

ReadWriteLock接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

ReadWriteLock里面只定义了两个方法:一个用来获取读锁,一个用来获取写锁。也就是说将文件的读写操作分开,分成2个锁来分配给线程,从而使得多个线程可以同时进行读操作,ReentrantReadWriteLock实现了ReadWriteLock接口。

ReentrantReadWriteLock接口

ReentrantLock(排他锁)具有完全互斥排他的效果,即同一时刻只允许一个线程访问,这样做虽然保证了实例变量的线程安全性,但效率非常低下。ReadWriteLock接口的实现类ReentrantReadWriteLock读写锁就是为了解决这个问题。ReentrantReadWriteLock里面提供了很多丰富的方法,不过最主要的有两个方法:readLock()和writeLock()用来获取读锁和写锁。

读写锁维护了两个锁,一个是读操作相关的锁也成为共享锁,一个是写操作相关的锁也称为排他锁。通过分离读锁和写锁,其并发性比一般排他锁有了很大提升。

多个读锁之间不互斥,读锁与写锁互斥,写锁与写锁互斥(只要出现写操作的过程就是互斥的)。在没有线程Thread进行写入操作时,进行读取操作的多个Thread都可以获取读锁,而进行写入操作的Thread只有在获取写锁后才能进行写入操作。即多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写入操作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LockTest6 {

    public static void main(String[] args) {
        LockService6 lockService6 = new LockService6();
        Thread t1 = new LockUser6A(lockService6);
        t1.setName("读线程A");
        t1.start();

        Thread t2 = new LockUser6A(lockService6);
        t2.setName("读线程B");
        t2.start();

        Thread t3 = new LockUser6B(lockService6);
        t3.setName("写线程A");
        t3.start();

        Thread t4 = new LockUser6B(lockService6);
        t4.setName("写线程B");
        t4.start();
    }
}

class LockUser6A extends Thread{

    private LockService6 lockService6;

    public LockUser6A(LockService6 lockService6) {
        this.lockService6 = lockService6;
    }

    @Override
    public void run() {
        lockService6.read();
    }
}

class LockUser6B extends Thread{

    private LockService6 lockService6;

    public LockUser6B(LockService6 lockService6) {
        this.lockService6 = lockService6;
    }

    @Override
    public void run() {
        lockService6.write();
    }
}

class LockService6{

    private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    public void read() {
        try {
            lock.readLock().lock();
            System.out.println(Thread.currentThread().getName() + "获得读锁于" + System.currentTimeMillis());
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "接触读锁于" + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.readLock().unlock();
        }
    }

    public void write() {
        try {
            lock.writeLock().lock();
            System.out.println(Thread.currentThread().getName() + "获得写锁于" + System.currentTimeMillis());
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + "接触写锁于" + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.writeLock().unlock();
        }
    }
}

执行结果:
读线程B获得读锁于1633955419136
读线程A获得读锁于1633955419136
读线程B接触读锁于1633955420140
读线程A接触读锁于1633955420140
写线程A获得写锁于1633955420140
写线程A接触写锁于1633955421144
写线程B获得写锁于1633955421144
写线程B接触写锁于1633955422147

https://segmentfault.com/a/1190000020541622

https://www.cnblogs.com/myseries/p/10784076.html

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
Python基础(二十六):模块和包简单介绍
Python模块(Module),是⼀个 Python文件,以 .py 结尾,包含了 Python 对象定义和Python语句。模块能定义函数,类和变量,模块里也能包含可执行的代码。
Lansonli
2023/01/26
7240
Python基础(二十六):模块和包简单介绍
1.自定义模块
​ 一个函数封装一个功能,你使用的软件可能就是由n多个函数组成的(先备考虑面向对象)。比如抖音这个软件,不可能将所有程序都写入一个文件,所以咱们应该将文件划分,这样其组织结构要好并且代码不冗余。加入分了10个文件,每个文件里面可能都有相同的功能(函数),怎么办?所以将这些相同的功能封装到一个文件中,那么这个存储着很多常用的功能的py文件,就是模块。 模块就是文件,存放一堆常用的函数,谁用谁拿。怎么拿?比如:我要策马奔腾共享人世繁华,应该怎么样?我应该骑马,你也要去浪,你是不是也要骑马。 我们说一个函数就是一个功能,那么把一些常用的函数放在一个py文件中,这个文件就称之为模块,模块,就是一些列常用功能的集合体。
changxin7
2019/09/10
5340
1.自定义模块
Python进阶教程笔记(四)模块和包
Python语言本身提供了非常多的模块,比如数学模块math、cmath、decimal、statistics;文件模块pathlib、stat、shutil等;除了使用官方模块,有时候也需要自定义模块。
Lemon黄
2020/10/30
5160
(九) 初遇python甚是喜爱之Modules模块操作
各位读者大大们大家好,今天学习python的Modules模块操作,并记录学习过程欢迎大家一起交流分享。
XXXX-user
2019/07/23
3640
(九) 初遇python甚是喜爱之Modules模块操作
【从零学习python 】37.Python自定义模块的使用和注意事项
除了使用系统提供的内置模块以外,我们还能自己写一个模块供自己的程序使用。一个.py文件就是一个模块,所以,自定义模块很简单,基本上相当于创建一个.py文件。但是,需要注意的是,如果一个.py文件要作为一个模块被别的代码使用,这个.py文件的名字一定要遵守标识符的命名规则。
全栈若城
2024/02/29
1610
【语法05】Python模块
在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了。
用户7886150
2021/01/07
4140
python模块与包揭秘
我们首先导入了math模块,然后利用math模块中的sqrt函数计算了4的平方根。让我们再细致一点来看待这个问题。 我在之前提到过,其实import也是执行了一个赋值操作,它把我们需要导入的目标模块对象赋值给了对应的变量名,例如上例就是把math模块对象赋值给了math这个变量名,然后math所指向的模块对象中的内容(函数、最外层的变量)都可以认为是math这个对象的属性(方法),所以我们可以用object.attr的形式来访问。
tnt阿信
2020/08/05
5060
python模块与包揭秘
Python 自定义模块
1.import 模块名:导入模块中的所有内容(引入多个用逗号分隔) import random,time
用户7886150
2021/01/21
8730
Python教程(17)——python模块是什么?python模块详解
模块是一个包含了Python定义和语句的文件,可用于将功能组织成可重用和可维护的代码块。每个Python文件都可以作为一个模块,模块可以包含变量、函数、类或可执行代码。通过使用模块,我们可以将代码分离成逻辑单元,促进模块化编程。所以我们可以简单的理解为,一个py文件就是一个模块,大部分情况都是这样的。
一点sir
2024/01/10
1750
Python教程(17)——python模块是什么?python模块详解
【Python】从基础到进阶(五):探究Python中的函数与模块
在前几篇文章中,我们已经学习了Python的基本语法、控制流以及数据操作等核心概念。这些知识使我们能够编写出简单但功能完备的程序。
空白诗
2024/08/29
1770
【Python】从基础到进阶(五):探究Python中的函数与模块
python基础教程:模块高级技巧
上一节,我们讲解了Python模块的基础知识,这一节我们继续深入了解模块的更多知识,从而让大家全面了解、掌握和运用模块到我们实际的编程中。
一墨编程学习
2019/05/15
8440
挑战30天学完Python:Day12 模块Modules
模块是在应用程序中一个包含一组代码或一组函数的文件。模块可以是包含单个变量、函数或大型代码库的文件。
MegaQi
2023/10/21
2120
挑战30天学完Python:Day12 模块Modules
Python学习笔记5—Python模块
    默认情况下,python第三方的模块安装在python 的安装目录下site-packages下,以文件或者目录的形式存放
py3study
2020/01/10
3570
python3--模块和包,软件开发规范
在第一次导入某个模块时(比如my_module),会检查该模块是否已经被加载到内存中(执行文件的名称空间对应的内存),如果有则直接引用,如果没有,解释器则会查找同名的内建模块,如果还没有找到就从sys.path给出的目录列表中依次寻找my_module.py文件
py3study
2018/08/02
7280
Python基础13-模块的使用
-多年互联网运维工作经验,曾负责过大规模集群架构自动化运维管理工作。 -擅长Web集群架构与自动化运维,曾负责国内某大型金融公司运维工作。 -devops项目经理兼DBA。 -开发过一套自动化运维平台(功能如下): 1)整合了各个公有云API,自主创建云主机。 2)ELK自动化收集日志功能。 3)Saltstack自动化运维统一配置管理工具。 4)Git、Jenkins自动化代码上线及自动化测试平台。 5)堡垒机,连接Linux、Windows平台及日志审计。 6)SQL执行及审批流程。 7)慢查询日志分析web界面。
DriverZeng
2022/09/26
4010
Python基础13-模块的使用
python模块和包
一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py 的后缀。
超蛋lhy
2018/08/31
1.4K0
Python - 模块与包
如果你在 51 Testting 上面见到这篇文章,不要以为我是盗版哦!因为那是我投稿的文章
小菠萝测试笔记
2020/06/19
6810
Python面试常见问题集锦:基础语法篇
在求职Python开发岗位的过程中,扎实掌握基础语法是成功应对面试的关键。本篇博客将聚焦Python基础语法,梳理面试中常见的问题、易错点,并提供实用的代码示例,帮助您在面试中展现出深厚的技术功底,从容应对挑战。
Jimaks
2024/04/16
2590
图解python | 模块
教程地址:http://www.showmeai.tech/tutorials/56
ShowMeAI
2022/02/23
5430
图解python | 模块
Python类、模块、包的区别
模块,在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。你在其他需要这些功能的文件中,导入这模块,就可重用这些函数和变量。一般用module_name.fun_name,和module_name.var_name进行使用。这样的语义用法使模块看起来很像类或者名字空间,可将module_name 理解为名字限定符。模块名就是文件名去掉.py后缀。
hbbliyong
2018/08/01
1.2K0
相关推荐
Python基础(二十六):模块和包简单介绍
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验