精华内容
下载资源
问答
  • 开启MicroPython多线程模式

    千次阅读 2019-01-27 22:31:16
    开启MicroPython多线程模式MicroPython官方版本对多线程的支持修改后的MicroPython多线程示例代码运行效果 MicroPython官方版本对多线程的支持 MicroPython官方版本尝试对 多线程 的支持,但是目前的支持只停留在...

    MicroPython官方版本对多线程的支持

    MicroPython官方版本尝试对 多线程 的支持,但是目前的支持只停留在非常初级的阶段,离真正可用还是有一段距离。在尝试增加多线程的支持过程中踩坑无数,不过最后总算成功实现所需要的功能。

    修改后的MicroPython多线程示例

    多线程的基础上增加了线程锁和信号量的支持:

    from umachine import Pin
    import utime
    import _thread
    
    lock = _thread.allocate_lock()
    semp = _thread.allocate_semephare()
    

    定义4个用户线程,分别是信号量演示线程/i2c演示线程/LED演示线程和MQTT消息发布线程:

    def sem_thread():
    	while True:
            semp.pend()
            print('sem_thread run')
    
    def i2c_thread():
    	while True:
            print('i2c_thread read 0x57')
            i2c0.readfrom_mem(0x57, 0, 4)
            utime.sleep(10)
            print('i2c_thread read 0x5f')
            i2c0.readfrom_mem(0x5f, 0x9a, 6)
            utime.sleep(10)
            #_thread.exit()
    
    def led_thread(time_):
    	while True:
            print('led_thread on')
            led0.value(1)
            utime.sleep(time_)
            print('led_thread off')
            led0.value(0)
            utime.sleep(time_)
            semp.post()
    
    def mqtt_thread(time_):
    	while True:
            lock.acquire()
            print('mqtt_thread message 1')
            mqtt.publish('/home/bedroom/lamp', 'led on')
            mqtt.publish('/home/bedroom/speaker', 'music off')
            utime.sleep(time_)
            print('mqtt_thread message 2')
            mqtt.publish('/home/bedroom/lamp', 'led off')
            mqtt.publish('/home/bedroom/speaker', 'play music')
            utime.sleep(1)
            print('mqtt_thread message 3')
            mqtt.publish('/smart_home/bedroom/window', 'close window')
            utime.sleep(time_)
            lock.release()
            #_thread.exit()
    

    MQTT消息订阅回调函数和连接成功回调函数:

    def callback_on_connect(userdata, flags, rc):
            mqtt.subscribe('/home/bedroom/msgbox', 0)
    
    def callback_on_message(userdata, message):
            print(message)
            mqtt.publish('/home/bedroom/air', 'air turn on')
    

    Wi-Fi连接到AP的Python代码(自己写的ATWINC1500 MicroPython库):

    from winc1500 import WLAN
    wlan = WLAN(STA_IF)
    wlan.connect('KSLINxxxxxx', 'xxxxxxxxx', AUTH_WPA_PSK)
    

    MQTT的连接和订阅(参考前面回调函数):

    from winc1500 import MQTT
    mqtt = MQTT(MQTT_CLIENT)
    mqtt.username_pw_set('winc_mp_mqtt', '')
    mqtt.on_connect(callback_on_connect)
    mqtt.on_message(callback_on_message)
    mqtt.connect('iot.eclipse.org', 1883, 30)
    

    最后是开始启动线程的操作

    _thread.start_new_thread(led_thread, (2,))
    _thread.start_new_thread(i2c_thread, ())
    _thread.start_new_thread(sem_thread, ())
    _thread.start_new_thread(mqtt_thread,(3,))
    
    while True:
            pass
    

    代码运行效果

    补充:MicroPython代码运行在Microchip SAMV71-XULT+ATWINC1500(Wi-Fi模组)4个用户线程运行效果

    展开全文
  • 多线程设计模式之保护性暂停模式

    万次阅读 2020-09-14 14:56:30
    多线程设计模式之保护性暂停模式 定义 保护性暂停模式(Guarded Suspension Design Pattern):当线程在访问某个对象时,发现条件满足时,就暂时挂起等待条件满足时再次访问。 如果某个结果需要在多线程之间传递,...

    多线程设计模式之保护性暂停模式

    定义

    保护性暂停模式(Guarded Suspension Design Pattern):当线程在访问某个对象时,发现条件不满足时,就暂时挂起等待条件满足时再次访问。

    如果某个结果需要在多线程之间传递,则可以让这些线程关联到一个对象GuardedObject,但是如果这个结果需要不断的从一个线程到另一个线程那么可以使用消息队列(生产者/消费者)

    Thread.join()、Future就采用了保护性暂停模式。

    简单实现

    package com.morris.concurrent.pattern.guardedsuspension.v2;
    
    public class GuardedObject<V> {
    
        private final Object lock = new Object();
    
        private V v;
    
        private boolean isFinished;
    
        public void set(V v) {
            synchronized (lock) {
                this.v = v;
                isFinished = true;
                lock.notifyAll();
            }
        }
    
        public V get() throws InterruptedException {
            synchronized (lock) {
                while (!isFinished) {
                    lock.wait();
                }
            }
            return v;
        }
    }
    

    超时实现

    public V get(long millis) {
        synchronized (lock) {
            while (!isFinished) {
                try {
                    lock.wait(millis);
                    break;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return v;
    }
    

    上面的超时实现有点小问题。

    分析:假如超时时间是5s,但是在第2s的时候别人把这个线程中断了但是此时还没有结果,那么这个线程就会进入下次循环继续等待5s,这样这个线程就等待7s了。

    最终实现如下:

    public V get(long millis) {
        long begin = System.currentTimeMillis(); // 等待开始时间
        long waitedTime = 0; // 等待了多长时间
        synchronized (lock) {
            while (!isFinished) {
                if(waitedTime >= millis) {
                    System.out.println("超时了,不等了");
                    break;
                }
                try {
                    lock.wait(millis - waitedTime); // 继续等待剩余时间
                    break;
                } catch (InterruptedException e) {
                    waitedTime = System.currentTimeMillis() - begin;
                    System.out.println("被中断了,等了" + waitedTime + "ms");
                }
            }
        }
        return v;
    }
    

    使用保护性暂停模式实现Future和Callable

    public interface Callable<T> {
        T call();
    }
    
    public interface Future<T> {
        T get();
    }
    
    public class FutureTask<T> implements Future<T> {
    
        private boolean isFinish;
    
        private T t;
    
        public synchronized void set(T t) {
            this.t = t;
            this.isFinish = true;
            this.notifyAll();
        }
    
        @Override
        public synchronized T get() {
            while (!isFinish) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return t;
        }
    }
    
    public abstract class Executors {
    
        public static <T> Future<T> newSingleThreadPool(Callable<T> callable) {
            FutureTask<T> future = new FutureTask<>();
            new Thread(()->{
                T t = callable.call();
                future.set(t);
            }).start();
            return future;
        }
    
    }
    
    展开全文
  • 单例模式多线程安全

    千次阅读 2019-04-23 00:20:14
    单例模式多线程安全 大厂面试题: 1、请你谈谈对volatile的理解? 2、CAS你知道吗? 3、原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗? 4、我们都知道ArrayList是线程安全的,请编码写一个...

    单例模式多线程下不安全

    大厂面试题:

    1、请你谈谈对volatile的理解?

    2、CAS你知道吗?

    3、原子类AtomicInteger的ABA问题谈谈?原子更新引用知道吗?

    4、我们都知道ArrayList是线程不安全的,请编码写一个不安全的案例并给出解决方案?

    5、公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁。

    6、CountDownLatch、CyclicBarrier、Semaphore使用过吗?

    7、阻塞队列知道吗?

    8、线程池用过吗?ThreadPoolExecutor谈谈你的理解?

    9、线程池用过吗?生产上你是如何设置合理参数?

    10、死锁编码及定位分析?

     

    1、单例模式单线程下是安全的

    public class SingletonDemo {

        private static SingletonDemo singletonDemo = null;

     

        private SingletonDemo() {

            System.out.println(Thread.currentThread().getName() + "\t" + "SingletonDemo构造方法创建");

        }

     

        public static SingletonDemo getInstance() {

            if (singletonDemo == null) {

                singletonDemo = new SingletonDemo();

            }

            return singletonDemo;

        }

     

        public static void main(String[] args) {

    // 单线程main情况下,单例模式下只会创建一次SingletonDemo对象

    System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());

    System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());

    System.out.println(SingletonDemo.getInstance() == SingletonDemo.getInstance());

        }

    }

    程序执行结果如下:

     

    2、单例模式多线程是不安全的

    public class SingletonDemo {

        private static SingletonDemo singletonDemo = null;

     

        private SingletonDemo() {

            System.out.println(Thread.currentThread().getName() + "\t" + "SingletonDemo构造方法创建");

        }

     

        public static SingletonDemo getInstance() {

            if (singletonDemo == null) {

                singletonDemo = new SingletonDemo();

            }

            return singletonDemo;

        }

     

        public static void main(String[] args) {

            // 多线程情况下,单例模式存在线程不安全,会创建多次SingletonDemo对象

            for (int i = 0; i < 10; i++) {

                new Thread(() -> {

                    SingletonDemo.getInstance();

                }, String.valueOf(i)).start();

            }

     

        }

    }

    程序执行结果如下:

    3、单例模式多线程不安全问题解决

    public class SingletonDemo {

        private static SingletonDemo singletonDemo = null;

     

        private SingletonDemo() {

            System.out.println(Thread.currentThread().getName() + "\t" + "SingletonDemo构造方法创建");

        }

     

        public static synchronized SingletonDemo getInstance() {

            if (singletonDemo == null) {

                singletonDemo = new SingletonDemo();

            }

            return singletonDemo;

        }

     

        public static void main(String[] args) {

            // 多线程情况下,单例模式存在线程不安全,会创建多次SingletonDemo对象

            for (int i = 0; i < 10; i++) {

                new Thread(() -> {

                    SingletonDemo.getInstance();

                }, String.valueOf(i)).start();

            }

     

        }

    }

    程序执行结果如下:

    volatile使用场景请接着看下一篇博客

    参考答案请看下一小节:单例模式volatile分析

     

    展开全文
  • 本例来自《java多线程编程调试模式》: 题意:模拟流水线上的工人,  工人一直在流水线上作业,零件(可看作客户端发的请求)一到达,工人就开始进行工作,无零件时工作处于等待状态 具体的业务代码有详注释: ...

    一.本例来自《java多线程编程调试模式》:

    题意:模拟流水线上的工人,

     工人一直在流水线上作业,零件(可看作客户端发的请求)一到达,工人就开始进行工作,无零件时工作处于等待状态

    具体的业务代码有详注释:

    一测试类:
    package worker.thread.pattern;
    
    public class Main {
        public static void main(String[] args) {
        	 Channel channel = new Channel(5);   // Worker Thread数量
             channel.startWorkers();
             ClientThread alice = new ClientThread("Alice", channel);
             ClientThread bobby = new ClientThread("Bobby", channel);
             ClientThread chris = new ClientThread("Chris", channel);
             alice.start();
             bobby.start();
             chris.start();
    
             try {
                 Thread.sleep(5000);
             } catch (InterruptedException e) {
             }
             alice.stopThread();
             bobby.stopThread();
             chris.stopThread();
             channel.stopAllWorkers();
        }
    }
    

    2.客户端类:主要发送工作请求
    package worker.thread.pattern;
    
    import java.util.Random;
    
    /**
     * 不停的发送请求给工人类
     * 
     * 1.创建请求实例,并将实例发送给管理工人线程的类
     * 
     * @author lxb
     *
     */
    public class ClientThread extends Thread {
    
    	private final Channel channel;
    	private static final Random random = new Random();
    
    	private volatile boolean terminated = false; // 停止请求标志
    
    	public ClientThread(String name, Channel channel) {
    		super(name);
    		this.channel = channel;
    	}
    
    	public void run() {
    		try {
    			for (int i = 0; !terminated; i++) {
    				try {
    					Request request = new Request(getName(), i);
    					channel.putRequest(request);
    					Thread.sleep(random.nextInt(1000));
    				} catch (InterruptedException e) {
    					terminated = true;
    				}
    			}
    		} finally {
    			System.out.println(Thread.currentThread().getName()
    					+ " is terminated.");
    		}
    	}
    
    	public void stopThread() {
    		terminated = true;
    		interrupt();
    	}
    }
    

    3.请求对象:

    package worker.thread.pattern;
    
    import java.util.Random;
    
    /**
     * 请求实体类
     * @author lxb
     *
     */
    public class Request {
    
    	private final String name; //  
        private final int number;  // 
        private static final Random random = new Random();
        public Request(String name, int number) {
            this.name = name;
            this.number = number;
        }
        public void execute() {
            System.out.println(Thread.currentThread().getName() + " executes " + this);
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
            }
        }
        public String toString() {
            return "[ Request from " + name + " No." + number + " ]";
        }
    }
    

    4.请求队列与工人线程管理类:
    package worker.thread.pattern;
    
    /**
     * 用来接受客户端线程发来的请求、将请求传递给工人线程,所以至少需要以下数据结构:
     * 1.一个队列来保存客户端发来的请求,还必须提供两个接口,一个putRequest保存请求, 另一个是取出请求takeRequest
     * 2.线程池来管理各个工人线程,这个池可以是一个线程数组,数组大小可自定义
     * 
     * @author lxb
     *
     */
    public class Channel {
    
    	private static final int MAX_REQUEST = 100; // 假设最大的请求队列值
    
    	private final Request[] requestQueue; // 保存的请求队列
    
    	private int tail;
    	private int head;
    	private int count; // 请求队列中的请求数量
    
    	private final WorkerThread[] threadPool; // 工人线程池
    
    	public Channel(int threads) {
    
    		this.requestQueue = new Request[MAX_REQUEST];
    		this.head = 0;
    		this.count = 0;
    		this.tail = 0;
    		threadPool = new WorkerThread[threads];
    
    		for (int i = 0; i < threadPool.length; i++) {
    			 threadPool[i] = new WorkerThread("Worker-" + i, this);
    		}
    	}
    	
    	/**
    	 * 开启工作线程
    	 */
    	public void startWorkers() {
    		for (int i = 0; i < threadPool.length; i++) {
    			threadPool[i].start();
    		}
    	}
    	
    	public void stopAllWorkers(){
    		for(int i=0;i<threadPool.length;i++){
    			threadPool[i].stopThread();
    		}
    	}
    
    	/**
    	 * 保存客户端发来的工作请求
    	 * 
    	 * @param request
    	 * @throws InterruptedException 
    	 */
    	public synchronized void putRequest(Request request) throws InterruptedException {
    		while (count >= requestQueue.length) {
    			wait();
    		}
    
    		requestQueue[tail] = request;
    
    		tail = (tail + 1) % requestQueue.length;
    
    		count++;
    
    		notifyAll();
    	}
    
    	public synchronized Request takeRequest() throws InterruptedException {
    		while (count <= 0) {
    			wait();
    		}
    
    		Request request = requestQueue[head];
    		head = (head + 1) % requestQueue.length;
    
    		count--;
    		notifyAll();
    		return request;
    	}
    
    }
    

    5工人线程:

    package worker.thread.pattern;
    
    /**
     * 工作线程,处理客户端发来的具体的工作请求
     * @author lxb
     *
     */
    public class WorkerThread extends Thread{
    
    	private final Channel channel;
    	private volatile boolean terminated = false;	//停止请求标志
    	
    	public WorkerThread(String name,Channel channel){
    		super(name);
    		this.channel = channel;
    	}
    	
    	public void run() {
            try {
                while (!terminated) {
                    try {                                           
                        Request request = channel.takeRequest();    
                        request.execute();                          
                    } catch (InterruptedException e) {
                        terminated = true;
                    }                                               
                }
            } finally {
                System.out.println(Thread.currentThread().getName() + " is terminated.");
            }
        }
        public void stopThread() {
            terminated = true;
            interrupt();
        }
    }
    




    展开全文
  • Java基础之单例模式多线程环境下的安全问题 目录: 单线程下的单例模式 多线程下的单例模式 单例模式volatile分析 1. 单线程下的单例模式 1. 单线程下单例模式代码 public class SingletonDemo {...
  • 多线程设计模式——最后总结

    千次阅读 2016-07-16 14:55:20
    多线程设计模式 最后总结
  • 线程模式

    千次阅读 2015-08-09 16:10:30
    创建多线程应用的第一步
  • 万字图解Java多线程

    万次阅读 多人点赞 2020-09-06 14:45:07
    java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却知道怎么下手,实际上还是多线程这块知识了解深刻,知道多线程api的应用场景,知道多线程的运行流程等等,...
  • C# 多线程模式 关闭/退出全部线程

    千次阅读 2014-03-22 23:03:24
    今天使用VS调试一个Http服务器,其中使用了多个Thread来多线程处理Request,发现在调试模式下,关闭程序时,VS还处于调试模式,猜测是因为有Thread没有结束   Google 一下, 得出以下解决方法 Thread.IsBackground ...
  • 彻头彻尾理解单例模式多线程

    万次阅读 多人点赞 2017-03-20 16:26:03
    多线程环境下,我们特别介绍了五种方式来在多线程环境下创建线程安全的单例,使用synchronized方法、synchronized块、静态内部类、双重检查和ThreadLocal实现懒汉式单例,并给出实现效率高且线程安全的单例所需要...
  • 多线程下的单例模式实现

    千次阅读 2019-02-11 18:00:38
    多线程下的单例模式实现一,单线程下的单实例1, 懒汉模式2, 饿汉模式二,多线程下的单实例1,加锁2,原子操作 &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;单实例设计模式是我们平常...
  • C++单例模式:单例模式遇到多线程

    千次阅读 多人点赞 2018-02-09 21:10:39
    单例模式介绍 单例模式主要有2中形式,一种是饿汉式,一种是懒汉式。 饿汉式:程序一加载单例模式就已经创建了,也就很饥饿嘛。...当遇到多线程是,是线程安全的,但是我们可以使用加强版的也就是线
  • 单例模式多线程中的安全性研究

    千次阅读 2016-04-06 14:13:33
    关于一般单例模式的创建和分析在我的另一篇博客《Java设计...只是在上篇博客中的单例是针对于单线程的操作,而对于多线程却并适用,本文就从单例模式多线程安全的角度出发,讲解单例模式多线程中应该如何被使用。
  • flask笔记:10:多线程模式

    万次阅读 2016-09-21 15:22:18
    app.run(debug=True,threaded=True) flask默认关闭多线程模式 threaded=True 开启多线程
  • 图解Java多线程设计模式

    千次阅读 2017-09-12 16:18:39
    图解Java多线程设计模式
  • 多线程中的单例模式

    万次阅读 2017-04-12 22:25:18
    多线程中的单例模式常用的主要有两种:1.静态内部类方法(饿汉模式)2.双重检测法(懒汉模式) 为什么要检测两次?原因是多个线程在synchronized上面阻塞了,第一个进入synchronized代码块的创建了新的对象,所以第...
  • reactor模式多线程的reactor模式

    千次阅读 2018-03-27 15:16:17
    单线程的reactor模式并没有解决IO和CPU处理速度匹配问题,所以多线程的reactor模式引入线程池的概念,把耗时的IO操作交由线程池处理,处理完了之后再同步到selectionkey中,服务器架构图如下     上文...
  • 国内首部Java多线程设计模式原创作品《Java多线程编程实战指南(设计模式篇)》已由电子工业出版社出版。本书从理论到实战,用生活化的实例和通俗易懂的语言全面介绍Java多线程编程的"三十六计"——多线程设计模式
  • 单例模式多线程

    千次阅读 2019-11-13 17:22:41
    如何使单例模式遇到多线程是安全的、正确的? 我们在学习设计模式的时候知道单例模式有懒汉式和饿汉式之分。简单来说,饿汉式就是在使用类的时候已经将对象创建完毕,懒汉式就是在真正调用的时候进行实例化操作。...
  • Java多线程

    万次阅读 多人点赞 2021-06-11 16:28:49
    Java多线程Java多线程线程的创建线程常见方法线程的状态线程的优先级守护线程线程组Java线程池线程池的创建线程池的参数线程池的使用线程安全问题Java中的锁synchronized同步方法synchronized同步语句块...
  • Redis面试题(一): Redis到底是多线程还是单线程?

    万次阅读 多人点赞 2018-04-02 18:18:36
    0.redis单线程问题单线程指的是网络请求模块使用了一个线程(所以需考虑并发安全性),即一个线程处理所有网络请求,其他模块仍用了线程。1.为什么说redis能够快速执行(1) 绝大部分请求是纯粹的内存操作(非常...
  • 来源于:《java多线程设计模式》一书  本例的类结构图: 2.Data类: package read.write.pattern; /** * 读者与写者共同要访问的数据类 * @author lxb * */ public class Data { private final char[] ...
  • java多线程之Future模式使用

    千次阅读 2018-01-10 10:39:56
    传统单线程环境下,调用函数是同步的,必须等待程序返回结果后,才可进行其他处理。 Futrue模式下,调用方式改为异步。 Futrue模式的核心在于:充分利用主函数中的等待时间,利用等待时间处理其他任务,充分利用...
  • Java多线程编程中不变模式的详解

    千次阅读 2014-11-12 18:28:09
    Java多线程编程中,常用的多线程设计模式包括:Future模式、Master-Worker模式、Guarded Suspeionsion模式、不变模式和生产者-消费者模式等。这篇文章主要讲述……,关于其他多线程设计模式的地址如下: 关于Future...
  • Java 多线程:彻底搞懂线程池

    万次阅读 多人点赞 2019-07-09 19:27:00
    熟悉Java多线程编程的同学都知道,当我们线程创建过多时,容易引发内存溢出,因此我们就有必要使用线程池的技术了。 目录 1 线程池的优势 2 线程池的使用 3 线程池的工作原理 4 线程池的参数 4.1 任务队列...
  • 我们已经觉察出了当初设计模式的高瞻远瞩,但是也有一些不足,需要我们去改进,有人说过,世界上没有绝对的事,当然,再简单的事情,环境变了,也会发生变化,今天和大家一起分享在多线程下单例模式的优化。...
  • 这些都是根据我最近看的《Java实战指南多线程编程(设计模式篇)》所得整理。模式名称Guarded Suspension(保护性暂挂模式模式面对的问题多线程编程中,往往将一个任务分解为不同的部分,将其交由不同的线程来执行...
  • 多线程的 pipeline 设计模式

    千次阅读 2008-04-22 16:49:00
    一个简单例子:有很个html网页,网页的id、title、url、path等信息...一般的想法是使用个平行的线程,每个线程处理某个ID范围的网页。但是仔细分析就可以发现,对每个网页的处理可以分为以下处理步骤:读取数据库行
  • java多线程12种设计模式

    千次阅读 2014-07-09 22:22:15
    1、Single Threaded Execution Pattern(单线程执行模式)
  • Pipeline(流水线)模式

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 778,396
精华内容 311,358
关键字:

多线程模式开还是不开