精华内容
下载资源
问答
  • 工业机器人运用指令部分解析-详细

    千次阅读 2021-05-27 20:17:54
    工业机器人指令解析 目录 工业机器人指令解析

    工业机器人指令解析

    机器人常用指令

        IF - 如果满足条件,那么;否则
        
        MoveAbsJ - 移动机械臂至**接头位置
        
        MoveC - 使机械臂沿圆周移动
        
        MoveJ - 通过接头移动,移动机械臂
        
        MoveL - 使机械臂沿直线移动

        SetDO - 改变数字信号输出信号值

        SetGO - 改变一组数字信号输出信号的值

        Set - 设置数字信号输出信号

        StartMove - 重启机械臂移动
        
        Stop - 停止程序执行

        StopMove - 停止机械臂的移动

        WaitDI - 等待直至已设置数字信号输入信号

        WaitDO - 等待直至已设置数字信号输出信号

        WaitTime - 等待给定的时间

        num - 数值

        robtarget - 位置数据


    -------------------------------------------------------------------------------------
    机器人运用:
    1.waitTime:用于等待给定的时间
      例1:
      WaitTime 0.5;程序执行等待0.5秒
      程序执行等待的最短时间(以秒计)为0 s。
      最长时间不受限制。分辨率为0.001 s。
      详解:机器人程序指针执行到此条指令,必须等待0.5秒以后才继续往下执行!
      例2:
      WaitTime \InPos,0.5
      详解:在 WaitTime指令后面加入了Inpos参数的含义就是:机器人到位且完全停止后才开始计时,时间到达0.5秒以后才继续往下执行!
      例3:
      MoveJ p1, vmax, fine, tool2;      
      WaitTime \InPos,0.5;
      MoveJ p2, vmax, z30, tool2;
      详解:机器人到达P1位置点之后,并且机器人完全停止下来,才开始计时,时间到达0.5秒以后才机器人继续执行到达P2位置点。


    2. WaitDI:用于等待,直至已设置数字信号输入
      例1:
      WaitDI di4, 1;
      仅在已设置di4输入后,继续程序执行。
      详解:机器人程序指针执行到此条指令,需要等待开关信号di4为1的时候,才往下执行。
      例2:
      WaitDI di0,1\MaxTime:=3;
      详解:在WaitDI di0,1指令后面加上了可选参数MaxTime:=3,则表示允许的最长等待时间3秒。如果在3秒时间以内di0还没有为1,机器人则报错处理。

    3.输出信号指令:
     A、输出输出信号指令:set dol
     do1:输出信号名。(signaldo)将一个输出信号赋值为1。
     B、复位输出信号指令:Reset do1
     do1:输出信号名。(signaldo)将一个输出信号赋值为0。
     C、输出脉冲信号指令:ulseDO do1
     do1:输出信号名。(signaldo)输出一个脉冲信号,脉冲长度为0.2s。

    4.机器人指令列表分类解析:

    (1)Common常用的指令
    该分类下是我们最常用的指令。包括赋值、逻辑、运动等指令。

    (2)Prog.Flow(Controlling the program flow)控制程序流程类 
      
    在ABB机器人中,程序都是按照一定的顺序(也可以理解为按照指令的规划)执行的。除了按照由上至下的顺序执行外,我们还可以通过指令中断循序执行过程或者调用其它指令或程序,以处理执行期间可能出现的各种情况或者实现更加复杂的控制逻辑要求。 
      
    在ABB机器人中所有的控制流程都是基于以下的五种原理 
      
    1、调用另一程序(无返回值程序)并在执行该程序后,按指令继续执行; 
    2、基于是否满足给定条件,执行不同指令; 
    3、重复某一指令序列多次,直到满足给定条件; 
    4、移至同一程序中的某一标签; 
    5、终止程序执行过程。

    (3)Various(Various instructions)各种指令
     
    该分类下有如下四种指令:
    1、 给数据赋值;
    2、 等待一段指定时间或等到满足条件时;
    3、 在程序中插入注释;
    4、 加载编程模块。

    (4)Settings(Motion settings)运动设置
    该分类中包含了与机器人运动参数设置相关的指令

    (5)Motion&Proc/ Motion Adv./ MotionSetAdv运动
    运动类中包含了所有控制机器人运动的指令。

    (6)I/O(Input and output signals)输入输出
    该分类下包含有与机器人输入输出有关的信号

    (7)Communicate(Communication)通信
    该分类包含机器人与人和机器人与其它设备进行通信的指令

    (8)Interrupts中断
    该分类下包含有与中断程序有关的指令

    (9)Error Rec.(Error recovery)错误恢复
    该分类下包含有与错误相关的指令。

    (10)System & time系统与时间
    该分类里包含系统和时间指令支持用户测量、检查和记录时间。

    (11)Mathematics数学
    该分类下的指令用于计算与修改数据数值。

    (12)xt.computer(External computer communication)外部计算机通信
    该分类中包含与外部计算机通信相关的指令

    该分类下的指令在有的robotware版本中被合并到Communicate分类中了。


    (13)Multitasking& MultiMove多任务与多运动
    该分类下包含与多任务和多运动相关的指令

    (14)RAPID support(RAPID support instructions)RAPID配套指令
    包含与RAPID相配套的指令

    (15)Calib& service(Calibration & service)校准&服务
    该分类下包含用于校准和测试机器人本体的指令。

    (16)M.C1~ M.C3(Most Common Instruction)最常用的指令
    这是ABB机器人为我们预留的可供自定义修改指令列表的分类。
    在控制面板中的Man-machine communication主题中可以对该分类的内容进行个性化设置。
    指令列表的分类就是这些了,如果你的机器人的系统版本是robotware6.06及以上,那么指令列表中还有一个过滤器的功能也可以使用,让我们抛开分类的限制通过输入指令字母快速索引到你想使用的指令。


    展开全文
  •   接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现Lock wait timeout exceeded; try restarting transaction的错误 <-- java.sql.SQLException: Lock wait timeout exceeded; try restarting ...

    问题现象

      接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现Lock wait timeout exceeded; try restarting transaction的错误

    <-- java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction
        at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1074)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4120)
        at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4052)
        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2503)
        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2664)
        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2794)
        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2155)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2458)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2375)
        at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2359)
        at com.trs.components.wcm.publish.element.PublishContentDocumentImpl.setPublishTimeAndURL(PublishContentDocumentImpl.java:851)
        at com.trs.components.common.publish.domain.publisher.PageGenerator.updateContentPublishTime(PageGenerator.java:236)
        at com.trs.components.common.publish.domain.publisher.PageGenerator.generateDetail(PageGenerator.java:216)
        at com.trs.components.common.publish.domain.taskdispatch.PageTaskWorker.executeTask(PageTaskWorker.java:278)
        at com.trs.components.common.publish.domain.taskdispatch.PageTaskWorker.run(PageTaskWorker.java:153)
        at com.trs.components.common.publish.domain.taskdispatch.ThreadPool$Worker.run(ThreadPool.java:56)

     

    问题场景

      1、在同一事务内先后对同一条数据进行插入和更新操作;

      2、分布式服务操作同一条记录;

      3、瞬时出现高并发现象;

     

    问题原因

      1、在高并发的情况下,Spring事物造成数据库死锁,后续操作超时抛出异常。

      2、Mysql数据库采用InnoDB模式,默认参数:innodb_lock_wait_timeout设置锁等待的时间是50s,一旦数据库锁超过这个时间就会报错

     

    解决方法

    方法一:调整超时参数

    mysql官方文档如下:

    当锁等待超时后innodb引擎报此错误,等待时间过长的语句被回滚(不是整个事务)。如果想让SQL语句等待其他事务更长时间之后完成,你可以增加参数innodb_lock_wait_timeout配置的值。如果有太多长时间运行的有锁的事务,你可以减小这个innodb_lock_wait_timeout的值,在特别繁忙的系统,你可以减小并发。

    InnoDB事务等待一个行级锁的时间最长时间(单位是秒),超过这个时间就会放弃。默认值是50秒。一个事务A试图访问一行数据,但是这行数据正在被另一个innodb事务B锁定,此时事务A就会等待事务B释放锁,等待超过innodb_lock_wait_timeout设置的值就会报错ERROR 1205 (HY000):

    innodb_lock_wait_timeout是动态参数,默认值50秒,最小值是1秒,最大值是1073741824;

    set innodb_lock_wait_timeout=1500等价于set session只影响当前sessio。set global innodb_lock_wait_timeout=1500作为全局的修改方式,只会影响修改之后打开的session,不能改变当前session。

    mysql> set GLOBAL innodb_lock_wait_timeout=1500;

     

    方法二:解决死锁

    1、查看数据库当前的进程

    show processlist会显示出当前正在执行的sql语句列表,找到消耗资源最大的那条语句对应的id.

    mysql> show processlist; 
    +---------+------+-------------------+--------------------+---------+-------+-------+------------------+
    | Id      | User | Host              | db                 | Command | Time  | State | Info             |
    +---------+------+-------------------+--------------------+---------+-------+-------+------------------+
    | 3205081 | root | 172.19.2.8:50317  | ********           | Sleep   | 16485 |       | NULL             |
    | 3210354 | root | 172.19.2.8:51066  | information_schema | Sleep   |  3569 |       | NULL             |
    | 3210630 | root | 172.19.2.12:61845 | ********           | Query   |     0 | init  | show processlist |
    +---------+------+-------------------+--------------------+---------+-------+-------+------------------+
    10 rows in set (0.00 sec)

     

    2、查看当前的锁和事务

    在5.5中,information_schema 库中增加了三个关于锁的表(inndodb引擎):

    • innodb_trx         ## 当前运行的所有事务
    • innodb_locks       ## 当前出现的锁,查看正在锁的事务
    • innodb_lock_waits  ## 锁等待的对应关系 ,查看等待锁的事务

    当前运行的所有事务

    mysql> SELECT * FROM information_schema.INNODB_TRX;

    当前出现的锁

    mysql> SELECT * FROM information_schema.INNODB_LOCKs;

    锁等待的对应关系

    mysql> SELECT * FROM information_schema.INNODB_LOCK_waits;

    看里面是否有正在锁定的事务线程,看看ID是否在show processlist里面的sleep线程中,如果是,就证明这个sleep的线程事务一直没有commit或者rollback而是卡住了

     

    3、查询产生锁的具体sql

    根据具体的sql,就能看出是不是死锁了,并且可以确定具体是执行了什么业务,是否可以kill;

    select 
        a.trx_id 事务id ,
        a.trx_mysql_thread_id 事务线程id,
        a.trx_query 事务sql 
    from 
        INFORMATION_SCHEMA.INNODB_LOCKS b,
        INFORMATION_SCHEMA.innodb_trx a 
    where 
        b.lock_trx_id=a.trx_id;

     

    4、杀掉死锁的事务

    查询出所有有锁的事务对应的线程ID(注意是线程id,不是事务id),通过information_schema.processlist表中的连接信息生成需要处理掉的MySQL连接的语句临时文件,然后执行临时文件中生成的指令。

    mysql> select concat('KILL ',a.trx_mysql_thread_id ,';') from INFORMATION_SCHEMA.INNODB_LOCKS b,INFORMATION_SCHEMA.innodb_trx a where b.lock_trx_id=a.trx_id;
    +------------------------+
    | concat('KILL ',id,';') |
    +------------------------+
    | KILL 3205081;            |
    | KILL 3210354;            |
    | KILL 3210630;            |
    +------------------------+
    18 rows in set (0.00 sec)

    如果太多的话可以导出到txt再批量执行

    mysql> select concat('KILL ',a.trx_mysql_thread_id ,';') from INFORMATION_SCHEMA.INNODB_LOCKS b,INFORMATION_SCHEMA.innodb_trx a where b.lock_trx_id=a.trx_id into outfile '/tmp/kill.txt';

    KILL命令允许自选的CONNECTION或QUERY修改符:KILL CONNECTION与不含修改符的KILL一样:它会终止与给定的thread_id有关的连接。KILL QUERY会终止连接当前正在执行的语句,但是会保持连接的原状。KILL命令的语法格式如下:

    KILL [CONNECTION | QUERY] thread_id

    运行kill命令

    mysql> kill 3205081;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> kill 3210354;
    Query OK, 0 rows affected (0.00 sec)

     

    参考:

    Lock wait timeout exceeded:http://blog.itpub.net/29654823/viewspace-2150471/

    MySQL事务锁问题:https://cloud.tencent.com/developer/article/1356959

    展开全文
  • JAVA多线程知识点

    2021-04-22 09:40:43
    线程等待(WAITING)相关方法 wait、notify、notifyAll:wait使当前获得锁的线程等待并释放锁和notify唤醒随机一个等待的线程来竞争锁及notifyAll唤醒所有等待的线程来竞争锁(只有持有锁的对象才能调用这些方法,...

    JAVA多线程知识点

    1. 线程基础

    1.1. 线程概念

    线程是操作系统能够进行运算调度的最小单位(程序执行流的最小单元)。

    它被包含在进程之中,是进程中的实际运作单位。

    一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

    1.2. 线程安全

    原子性:线程共享内存同一时间只有一个线程可以操作(synchronized关键字,互斥锁)。

    可见性:某个线程的操作可以立即被其他线程观察到(volatile关键字,强制刷新线程内该变量内存)。

    有序性:线程内指令顺序执行(现代CPU指令重排,乱序执行);在java中指令重排不影响单线程内的最终结果,但不保证多线程。

    1.3. 创建并启动线程的方法

    实现 Runnable 接口

    class ByRunnable implements Runnable{

    @Override

    public void run() {

    System.out.println("实现Runnable并实现run方法");

    }

    }

    Thread thread = new Thread(new ByRunnable());

    thread.start();//调用start以开启新线程

    thread.join();//阻止主线程在新线程之前结束

    继承 Thread 类

    class ByThread extends Thread{

    @Override

    public void run() {

    System.out.println("继承Thread并重写run方法");

    }

    }

    Thread thread = new ByThread();

    thread.start();

    thread.join();

    1.4. 线程状态

    使用Thread.currentThread().getState();可以获得当前线程状态,thread.getState();获得某一线程的状态。

    初始(NEW):新创建了一个线程对象,但还没有调用start()方法。

    运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。

    阻塞(BLOCKED):表示线程阻塞于锁。

    等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。

    超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。

    终止(TERMINATED):表示该线程已经执行完毕。

    1.5. 线程超时等待(TIMED_WAITING)相关方法

    线程睡眠(sleep),当持有锁时不释放锁!且sleep的线程无法从外部唤醒,但可被中断! try {

    //睡眠1000毫秒,在此期间不参与CPU资源竞争(线程调度)

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    //可能在睡眠结束前线程就被中断了

    e.printStackTrace();

    }

    线程让出(yield) //给CPU一个提示,让出本次线程调度,但参与下一次调度(进入线程等待队列),CPU可能会忽略本次让出

    Thread.yield();

    线程加入(join) Thread t = new Thread(()->{

    System.out.println("new Thread.....");

    });

    t.start();

    //将线程t加入当前线程,即告诉当前线程等待线程t结束或在1000毫秒后再继续

    t.join(1000);

    线程超时等待(wait),只有持有锁的对象才能调用这个方法且会释放锁! //使获得锁的obj对象所在线程进入等待,等待1000毫秒后自动被唤醒,或者被notify(notifyAll)唤醒

    obj.wait(1000);

    线程超时禁用(park) //等待到当前时间的1000毫秒结束禁用

    LockSupport.parkUntil(System.currentTimeMillis()+1000);

    //禁用当前线程10000纳秒

    LockSupport.parkNanos(10000);

    1.6. 线程等待(WAITING)相关方法

    wait、notify、notifyAll:wait使当前获得锁的线程等待并释放锁和notify唤醒随机一个等待的线程来竞争锁及notifyAll唤醒所有等待的线程来竞争锁(只有持有锁的对象才能调用这些方法,且notify和notifyAll只能唤醒在同一个锁对象下wait的线程) //模拟仓库

    ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>();

    //模拟生产者

    Thread producer = new Thread(()->{

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

    try {

    while (queue.size() < 5) {

    Thread.sleep(100);

    queue.add("prod"+(++i));

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    synchronized (queue) {

    //随机唤醒一个等待中的线程

    queue.notify();

    if(queue.size() >= 5) {

    try {

    //仓库满了使当前线程等待

    queue.wait();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    });

    //模拟消费者

    Thread consumer = new Thread(()->{

    for(;;){

    try {

    while (queue.size() > 0 ) {

    Thread.sleep(10);

    System.out.println(queue.poll());

    }

    } catch (InterruptedException e){

    e.printStackTrace();

    }

    synchronized (queue) {

    //唤醒所有其他线程,此时最多只有一个线程(生产者)在等待

    queue.notifyAll();

    if(queue.size()<=0) {

    try {

    //商品消费完了,使当前线程等待

    queue.wait();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    }

    });

    producer.start();

    consumer.start();

    producer.join();

    consumer.join();

    park和unpark:park使线程等待及unpark使线程结束等待,park时当持有锁时不释放锁!可以在外部被unpark唤醒! Thread t = new Thread(()->{

    System.out.println("new.....");

    LockSupport.park();//让线程进入等待

    System.out.println("over wait");

    });

    t.start();

    Thread.sleep(1000);

    System.out.println("main sleep 1000");

    LockSupport.unpark(t);//唤醒指定线程t

    /*控制台输出:

    new.....

    main sleep 1000

    over wait

    */

    2. synchronized关键字

    synchronized是同步、互斥、独占、可重入的锁

    synchronized锁住的是对象,当没有传入对象时:

    当对静态方法加锁时锁住的是当前类的class对象。

    当对实例方法枷锁时锁住的时当前实例对象(this)。

    在方法内使用synchronized时必须传入对象synchronized(obj){/*sync code*/}并锁住其代码块。

    synchronized锁住的对象才可以使用wait、notify、notifyAll。

    synchronized存在锁升级的概念

    当始终同时只有同一个线程竞争时,锁时处于偏向锁状态(markword只记录线程标识而不尝试加锁且不主动释放记录的线程标识,此时默认不会有其他线程竞争锁)。

    在获得锁的线程未结束时有线程来竞争锁,锁升级为轻量级锁(自旋锁,线程不调用系统函数进入CPU等待队列)。

    当竞争变大(10次)或者锁持续时间变长时,锁升级为重量级锁(调用系统函数使线程进入CPU等待队列)。

    3. volatile关键字

    保证线程可见性

    在java中有共享内存,也有线程内工作内存,当持有共享内存的值时先将共享内存中的值复制到工作内存,每次修改值时先修改工作内存,写回到共享内存的时机由CPU控制(线程之间不可见),可能出现A线程改变某一个线程共享变量的值后B线程无法及时看到更新后的值.当使用volatile关键字后,每次修改该变量都会及时回写到共享内存并通知其他线程.

    保证线程可见性的缓存一致性协议:Intel:MESI.

    禁止指令重排序

    指令不会被CPU和编译器优化乱序执行,而是按照程序流线性执行.

    volatile关键字在Double Check Lock(DCL)单例的应用 : public class Test {

    private static volatile Test INSTANCE;

    public int i;

    private Test(){i=100;}

    //懒汉单例

    public static final Test instance(){

    if (INSTANCE==null) {

    synchronized (Test.class) {

    //Double Check 双重检测

    if (INSTANCE==null) {

    //new一个对象分三步:

    //1.申请内存(对象成员变量赋初值);

    //2.初始化成员变量(按照代码要求赋值);

    //3.将new对象赋值给变量.

    //new的过程不是原子的,可以指令重排序.

    //初始化单例时,volatile保证不会乱序执行,其他线程不会得到未完全初始化的单例.

    //即如果指令重排序了,先赋值了对象变量,再初始化对象内成员变量,

    //另一个线程得到的单例可能是未完全初始化的,对象的变量i可能是初值0

    INSTANCE = new Test();

    }

    }

    }

    return INSTANCE;

    }

    }

    volatile不可避免的会降低程序执行效率.

    4. Atomic原子操作类及CAS

    CAS

    全称: Compare And Swap (比较并交换) 或者说 Compare And Set.

    以CAS做底层的锁是一种轻量级乐观锁,当前线程不会进入等待队列.默认很快就会得到锁

    CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B. 当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做.

    AtomicInteger::incrementAndGet底层的CAS

    //代码位于Unsafe.class

    @HotSpotIntrinsicCandidate

    public final int getAndAddInt(Object o, long offset, int delta) {

    int v;

    do {

    v = getIntVolatile(o, offset);

    } while (!weakCompareAndSetInt(o, offset, v, v + delta));

    return v;

    }

    @HotSpotIntrinsicCandidate

    public final boolean weakCompareAndSetInt(Object o, long offset,

    int expected,

    int x) {

    return compareAndSetInt(o, offset, expected, x);

    }

    @HotSpotIntrinsicCandidate

    public final native boolean compareAndSetInt(Object o, long offset,

    int expected,

    int x);

    CAS伪代码实现

    cas(value,expected,newValue){

    if(value == expected) value = newValue;

    else{

    //try again or fail

    }

    }

    CAS中的ABA问题

    A线程对变量I的预期值为0,由于从内存中获取I需要时间,此时其他线程先将变量I改为其他值后又改会0,虽然此时依然满足A线程的预期值,但不是原来的预期值了,此时就发生了ABA问题,如果此时的偷梁换柱影响业务,一般的解决方式是加版本号.

    原子类

    Unsafe类

    获取unSafe实例

    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");

    theUnsafe.setAccessible(true);

    Unsafe unsafe = (Unsafe)theUnsafe.get(Unsafe.class);

    利用Unsafe直接操作内存

    long l = unsafe.allocateMemory(8);//分配内存

    unsafe.setMemory(l,0L,(byte)0);//操作内存

    unsafe.freeMemory(l);//释放内存

    利用Unsafe直接生成并操作对象

    class My{

    int a = 111;

    }

    //直接生成实例

    My o = (My) unsafe.allocateInstance(My.class);

    long offset = unsafe.objectFieldOffset(My.class.getDeclaredField("a"));

    //直接通过偏移量操作对象属性

    unsafe.getAndSetInt(o,offset,1234);

    System.out.println(o.a);//输出 1234

    利用Unsafe操作CAS

    unsafe.compareAndSwapInt(obj,offset,intVal);

    unsafe.compareAndSwapLong(obj,offset,longVal)

    5. 各种JUC包下的同步锁

    5.1. ReentrantLock

    package test;

    import java.util.ArrayList;

    import java.util.concurrent.TimeUnit;

    import java.util.concurrent.atomic.AtomicInteger;

    import java.util.concurrent.locks.Condition;

    import java.util.concurrent.locks.Lock;

    import java.util.concurrent.locks.ReentrantLock;

    public class ThreadTest {

    private static final String thStr(){

    return Thread.currentThread().getId()+" "+Thread.currentThread().getName();

    }

    public static class ReentrantLockTest {

    private final static Lock lock1 = new ReentrantLock();//入参为true为公平锁,等待锁最久将获得锁

    private final static Lock lock2 = new ReentrantLock();

    private static final void doSomething() {

    String str = thStr();

    try {

    System.out.println(str);

    lock1.lock();

    System.out.println(str+" alloc lock");

    } catch (Exception e) {

    e.printStackTrace();

    } finally {

    System.out.println(str+" will free lock");

    lock1.unlock();

    }

    }

    //常规获得锁

    public final static void testLock() {

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

    new Thread(()->{

    doSomething();

    }).start();

    }

    try {

    Thread.sleep(2000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    //死锁

    public static final void deadLock() {

    //两个线程相互获取对方锁

    var t1 = new Thread(new DeadLockThread(lock1,lock2));

    var t2 = new Thread(new DeadLockThread(lock2,lock1));

    t1.start();

    t2.start();

    try {

    TimeUnit.MILLISECONDS.sleep(200);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    t1.interrupt();//中断线程1,使线程2获得锁

    try {

    TimeUnit.MILLISECONDS.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    private static final class DeadLockThread implements Runnable {

    private Lock lock1,lock2;

    public DeadLockThread(Lock lock1, Lock lock2) {

    this.lock1 = lock1;

    this.lock2 = lock2;

    }

    @Override

    public void run() {

    String str = thStr();

    try {

    lock1.lockInterruptibly();

    System.out.println(str+" acquire lock1");

    TimeUnit.MILLISECONDS.sleep(100);

    lock2.lockInterruptibly();

    System.out.println(str+" acquire lock2");

    } catch (Exception e) {

    e.printStackTrace();

    } finally {

    System.out.println(str+" will free lock1");

    lock1.unlock();

    System.out.println(str+" will free lock2");

    lock2.unlock();

    }

    }

    }

    //超时休眠重新尝试获取锁

    public static final void tryLockTest(){

    ArrayList threads = new ArrayList<>(8);

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

    threads.add(new Thread(()->{

    tryLock();

    }));

    }

    threads.forEach(thread -> thread.start());

    threads.forEach(t-> {

    try {

    t.join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    });

    }

    private static final void tryLock(){

    String str = thStr();

    try {

    while (!lock1.tryLock(1,TimeUnit.SECONDS)){

    System.out.println(str + " try acquire lock1 filed");

    Thread.sleep(300);

    }

    System.out.println(str + " acquire lock1");

    Thread.sleep(2000);

    } catch (Exception e) {

    e.printStackTrace();

    } finally {

    System.out.println(str+" attempt free lock1");

    lock1.unlock();

    }

    }

    //Condition等待和唤醒

    public static final void testCondition(){

    ArrayList threads = new ArrayList<>();

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

    if(i%2==0){

    threads.add(new Thread(()->ConditionTest.get()));

    }else{

    threads.add(new Thread(()->ConditionTest.put()));

    }

    }

    threads.forEach(t->t.start());

    }

    private static final class ConditionTest{

    private static final Condition condP = lock1.newCondition();

    private static final Condition condG = lock1.newCondition();

    private static final ArrayList list = new ArrayList<>();

    private static final AtomicInteger ai = new AtomicInteger(0);

    public static final void put(){

    String str = thStr();

    try {

    lock1.lock();

    System.out.println(str+" try put");

    if(list.size()>=3){

    System.out.println(str+" list size >=3 will await");

    condP.await(300,TimeUnit.MILLISECONDS);//线程进入等待,同时释放锁

    }

    list.add("item "+ai.incrementAndGet());

    if(list.size()>=1){

    System.out.println(str+" now list size "+list.size());

    condG.signalAll();//唤醒等待的锁

    }

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    System.out.println(str+" unlock put");

    lock1.unlock();

    }

    }

    public static final void get(){

    String str = thStr();

    try {

    lock1.lock();

    System.out.println(str+" try get");

    if(list.size()<=0){

    System.out.println(str+" list size <=0 will await");

    condG.await();

    }

    try {

    System.out.println(str+" "+list.remove(0));

    } catch (RuntimeException e){

    System.err.println(str+" list size is zero, will retry");

    get();

    }

    if(list.size()<3)

    condP.signalAll();

    } catch (InterruptedException e) {

    e.printStackTrace();

    } finally {

    System.out.println(str+" unlock get");

    lock1.unlock();

    }

    }

    }

    }

    }

    5.2. ReadWriteLock - StampedLock

    5.3. CountDownLatch

    5.4. CyclicBarrier

    5.5. Phaser

    5.6. Semaphore

    5.7. Exchanger

    5.8. LockSupport

    5.9. AbstractQueuedSynchronizer

    VarHandle

    java.lang.invoke.VarHandle:可以对对象普通属性进行原子操作,比反射快

    public class XXX{

    long x = 100L;

    private static VarHandle varHandle;

    static {

    try {

    varHandle = MethodHandles.lookup().findVarHandle(XXX.class,"x",long.class);

    } catch (Exception e) { e.printStackTrace(); }

    }

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

    var me = new XXX();

    System.out.println("x="+varHandle.get(me));//100

    varHandle.set(me,1000l);

    System.out.println("x="+me.x);//1000

    varHandle.compareAndSet(me,100l,10000l);//CAS

    System.out.println("x="+me.x);//1000

    }

    }

    5.10. 阻塞队列

    SynchronousQueue

    //容量为0的阻塞队列,用于线程间交换数据,直接将数据送往另一个线程

    public static SynchronousQueue synchronousQueue = new SynchronousQueue();

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

    new Thread(()->{

    try {

    //取出

    System.out.println(synchronousQueue.take());

    System.out.println(synchronousQueue.take());

    System.out.println("OVER2");

    } catch (Exception e) {

    e.printStackTrace();

    }

    }).start();

    //阻塞等待索取

    synchronousQueue.put("synchronousQueue2");

    synchronousQueue.put("synchronousQueue1");

    System.out.println("OVER1");

    }

    TransferQueue

    //提供独特的transfer方法,阻塞当前线程,直到被transfer放入的数据被取出

    public static TransferQueue transferQueue = new LinkedTransferQueue();

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

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

    new Thread(()->{

    try {

    //取出数据

    System.out.println(transferQueue.take());

    } catch (Exception e) {

    e.printStackTrace();

    }

    }).start();

    }

    //阻塞到被取出

    transferQueue.transfer("transferQueue1");

    System.out.println("transferQueue1over");

    transferQueue.transfer("transferQueue2");

    System.out.println("transferQueue2over");

    }

    DelayQueue

    static class MyDelayed implements Delayed{

    String msg;

    long time;

    public MyDelayed(String msg, long time) {

    this.msg = msg;

    this.time = time+System.currentTimeMillis();

    }

    @Override //到达执行时间的剩余时间

    public long getDelay(TimeUnit unit) {

    return unit.convert(time-System.currentTimeMillis(),TimeUnit.MILLISECONDS);

    }

    @Override //确定优先级

    public int compareTo(Delayed o) {

    return (int)(getDelay(TimeUnit.MILLISECONDS)-o.getDelay(TimeUnit.MILLISECONDS));

    }

    }

    public static DelayQueue delayQueue = new DelayQueue();

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

    delayQueue.add(new MyDelayed("asd3",2000l));

    delayQueue.add(new MyDelayed("asd1",1000l));

    delayQueue.add(new MyDelayed("asd2",1500l));

    MyDelayed myDelayed;

    while ((myDelayed=delayQueue.take())!=null)

    System.out.println(myDelayed.msg+" ,current: "+System.currentTimeMillis());

    }

    6. 线程池

    ThreadPoolExecutor

    //完整构造线程池

    public ThreadPoolExecutor(int corePoolSize, //核心线程数

    int maximumPoolSize, //最大线程数

    long keepAliveTime, //超过核心线程数的线程的最大空闲生存时间

    TimeUnit unit, //keepAliveTime的单位

    BlockingQueue workQueue, //线程队列,当线程数超过最大线程时入队

    ThreadFactory threadFactory, //线程工厂

    RejectedExecutionHandler handler) //当线程数满,队列满时的拒绝策略

    {

    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);

    }

    展开全文
  • 当一些 PHP 开启 MySQL 连线后, 没有成功关闭 MySQL 连线, 会有一大堆 ...执行上面的 MySQL 指令会出现很多 Sleep 的连线, 当这些 Sleep 的连线过多时, 很容易会触及 max_connections 的限制, 出现 too many con...

    当一些 PHP 开启 MySQL 连线后, 没有成功关闭 MySQL 连线, 会有一大堆 sleep 的 process, 在 MySQL 可以执行以下指令查看:

    mysql> SHOW PROCESSLIST;

    执行上面的 MySQL 指令会出现很多 Sleep 的连线, 当这些 Sleep 的连线过多时, 很容易会触及 max_connections 的限制, 出现 too many connections 的错误。

    在 MySQL 限制连线逾时的变量是 wait_timeout, 这个变量的默认值是 28800, 单位是秒, 即 8 个小时。这个数值真的十分大, 因为预计应该不会有程式每次执行要用上 8 个小时吧。

    要解决这个问题, 只要降低 wait_timeout 的数值, 那么每个 process 会在超过这个限制的秒数后, 自动将它 kill 掉。

    首先需要先用 root 登入 MySQL:

    $ mysql -u root -p

    登入后输入以下 MySQL 指令, 将 wait_timeout 及 interactive_timeout 设定成 300, 即每个连线最多保留 300 秒:

    mysql> SET @@GLOBAL.wait_timeout=300

    mysql> SET @@GLOBAL.interactive_timeout=300

    这时 wait_timeout 及 interactive_timeout 的设定便会立即生效, 但当下次重新启动 MySQL 后便会回复使用默认值, 需要修改 my.cnf 设定:

    $ sudo vi /etc/my.cnf

    在 [mysqld] 段落加入 wait_timeout 及 interactive_timeout 的设定, 即改成类似这样:

    [mysqld]

    interactive_timeout=300

    wait_timeout=300

    在 vi 储存盘案及离开:

    :wq

    下次重新启动 MySQL 便会自动使用新设定。

    你可能感兴趣的内容:

    展开全文
  • java.lang.Exception: ### Error updating ... Cause: java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction ### The error may involve defaultParameterMap ### The error occu...
  • 线程概要 Java

    2021-02-28 17:44:32
    线程进程和线程的区别串行:初期的计算机只能串行执行任务,大量时间等待用户输入批处理:预先将用户的指令集中成清单,批量串行处理用户指令,仍然无法并发执行进程:进程独占内存空间,保存各自运行状态,互相之间...
  • 问题现象:接口响应时间超长,耗时几十秒才返回错误提示,后台日志中出现Lock wait timeout exceeded; try restarting transaction的错误问题场景:1、在同一事务内先后对同一条数据进行插入和更新操作;2、多台...
  • 在执行一个指令的时候,执行了一个事务, 就是这个事务,平平常常,在今天却给我挖了一个深坑,开始事务之后的一个sql语句,始终没有执行,出现以下错误 百思不得其解,各种百度。总结了以下 1)发生这个问题的...
  • MySql Lock wait timeout

    2021-03-02 10:41:51
    mysql select * from information_schema.innodb_trx SELECT * from information_schema.`PROCESSLIST` WHERE ...https://dev.mysql.com/doc/refman/8.0/en/innodb-parameters.html#sysvar_innodb_lock_wait_timeout
  • 应用:机器人以单轴运行的方式运动至目标点,绝对不存在奇点,运动状态完全不可控,避免在正常生产中使用此指令,常用于检查机器人零点位置,指令中 TCP 与 Wobj 只与运行速度有关,与运动位置无关。常用于机器人六...
  • 9、等待指令WaitTime , Time Time:机器人等待时间s。(num) 等待指令只是让机器人程序运行停顿片刻。 10、赋值指令: Data:= , Value Data:被赋值的数据。(All) Value:数据被赋予的值。(SameasData) 举例: ...
  • 为什么A在TIME-WAIT状态必须等待2MSL的时间呢? 这有两个理由。第一,为了保证A发送的最后一个ACK报文段能够到达B。这个ACK报文段有可能丢失,因而使处在LAST-ACK状态的B收不到对已发送的FIN + ACK报文段的确认。B...
  • 界面最下端出现WAIT Time 口 sec .这个WAIT 是等待时间时使用的,口 输入1 代表等待1秒输入2 代表等待2秒....... 3、如图下所示:选择WAITFOR (这个WAITFOR是等待某信号时使用的,如等待输入信号IN)。界面最下端...
  • ABB机器人的指令详细介绍!!!

    千次阅读 2021-01-26 12:51:20
    等待传感器连接 WaitSyncTask - 在同步点等待其他程序任务 WaitTestAndSet - 等待,直至变量FALSE,随后设置 WaitTime - 等待给定的时间 WaitUntil - 等待直至满足条件 WaitWObj - 等待传送带上的工件 WarmStart - ...
  • 今日分享关于发那科机器人控制指令介绍,包括I/O指令、IF\SELECT指令WAIT指令、JMP/LBL指令、CALL指令以及FOR\ENDFOR指令的使用方法及注意事项。1.I/O指令I/O指令是改变向外围设备输出信号状态,或读出输入信号...
  • abb根本编程指令言语是什么?ABB用的机器人编程言语是RAPID。RAPID是一种高档程序设计言语,它首要用于操控ABB工业机器人,是由ABB在1994年和S4操控体系一同引入的,替代了ARLA编程言语。不同公司用的工业机器人的...
  • 8、等待指令WaitTime,Time Time:机器人等待时间s。(num) 等待指令只是让机器人程序运行停顿片刻。 9、赋值指令: Data:=Value Data:被赋值的数据。(All) Value:数据被赋予的值。 举例: ABB:=FALSE;(bool) ...
  • ABB机器人常用指令3.0

    2021-11-09 11:51:13
    文章目录1、机器人运动控制2、例行程序内的逻辑控制3、停止程序执行4、赋值指令5、等待指令6、关于位置的功能7、对输入输出信号的值进行设定8、程序的调用9、程序注释10、示教器上人机界面的功能11、Sockets 通信12...
  • 1、基本运动指令:MoveL:线性运动(Linear)MoveJ:关节轴运动(Joint)MoveC:圆周运动(Circular)p1:目标位置。(robtarget)v100:运行速度mm/s。(speeddata)z10:转弯区尺寸mm。(zonedata)tool1:工具中心点TCP。...
  • 在Object类的JavaDoc中,在方法wait(long timeout)中,如下所述“If the current thread is interrupted by any thread before or while it is waiting, then an InterruptedException is thrown”上述陈述中“之前”...
  • wait的用法总结大全

    千次阅读 2021-05-23 06:13:01
    wait的意思vt.& vi. 等候,等待,(尤指长期地)希望,盼望vi. 准备妥,在手边,可得到,可使用vt. 推迟,搁置,延缓变形:过去式: waited; 现在分词:waiting; 过去分词:waited;wait用法wait可以用作动词wait的基本...
  • ESC/POS指令集完整版

    2021-05-08 16:30:24
    【实例简介】个人精心整理的ESC/POS指令集,希望能帮助到打印机及打印机相关开发者TM-T88VTM-U220●TM-U230amePrint and return to Standard mode (in Page modeASCIIForma tHexDecimal12DEscriptionn Page mode, ...
  • AT指令框架

    2021-04-16 16:11:57
    里面分别存有at指令当前状态,下一状态,发送指令,接受正确应答指令指令发送后没有应答的超时时间,重发次数,串口状态,以及特殊处理函数。 特殊处理函数是用来处理非单纯应答正确即可的指令的,比如存
  • 下面是全部指令的简明列表,放在这里方便参考。之后重要的指令,勇哥要拿出来单独学习。系统管理相关命令Reset 将控制器重置为初始状态。SysConfig 显示系统设置参数。SysErr 返回最新的错误状态或警告状态。Date ...
  • moshell常用指令

    2020-12-23 05:15:50
    总结了一些moshell常用指令:moshell[ip]通过ip进入相应网元的moshell操作界面。moshell[mgw1]通过局标进入相应网元的moshell操作界面(需在~:\cygwin\home\YOURUSERID\moshell\sitefiles\ipdatebase文件添加"mgw110....
  • 最全的ABB机器人编程指令与函数

    千次阅读 2020-12-23 12:15:16
    原标题:最全的ABB机器人编程指令与函数1 指令AccSet-降低加速度ActEventBuffer - 事件缓冲启用ActUnit - 启用机械单元Add-增加数值AliasIO - 确定I/O 信号以及别名AliasIOReset-重置I/O 信号以及别名":=" - 分配一...
  • 等待传感器连接 WaitSyncTask - 在同步点等待其他程序任务 WaitTestAndSet - 等待,直至变量FALSE,随后设置 WaitTime - 等待给定的时间 WaitUntil - 等待直至满足条件 WaitWObj - 等待传送带上的工件 WarmStart - ...
  • ABB机器人常用指令

    千次阅读 多人点赞 2021-06-24 01:48:00
    ABB机器人常用指令 1、机器人运动指令 MoveJ(关节运动指令) MoveL(TCP直线运动指令) MoveC(TCP圆弧运动指令) MoveAbsJ(轴绝对角度位置运动指令) 2、例行程序内的逻辑控制 Compact IF (如果条件满足,就执行一条...
  • 这是一套AT指令收发程序,不仅可以控制集成AT指令的传感器模块,也可以把单片机当作AT模块处理其他设备发送的AT命令。该程序不仅适用于51单片机,也适用于其他单片机。 串口初始化以及收发程序 #include "usart.h" ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,561
精华内容 22,624
关键字:

waittime指令