显式锁示例

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/shy_snow/article/details/82690043

tryLock在一定时间内获取不到锁不会一直阻塞,会返回false,然后线程会继续向下走。

package com.iteye.yuanyuan7891.thread.lock;

import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestLock
{
    
    public static void main(String[] args)
        throws InterruptedException
    {
        new AThread("A").start();
        Thread.sleep(1000);
        new AThread("B").start();
        Thread.sleep(7000);
        new AThread("C").start();
    }
}

/**
 * 示例线程
 */
class AThread extends Thread
{
    public static volatile Lock dbInsertLock = new ReentrantLock();
    
    public static Lock getDbInsertLock()
    {
        return dbInsertLock;
    }
    
    String tName = null;
    
    AThread(String name)
    {
        super(name);
        this.tName = name;
    }
    
    @Override
    public void run()
    {
        try
        {
            System.out.println(tName + "等待锁" + new Date());
            if (dbInsertLock.tryLock(3, TimeUnit.SECONDS))
            {
                // if (dbInsertLock.tryLock(3, TimeUnit.SECONDS)){
                // System.out.println(tName+"可重入"+new Date());
                // }else{
                // System.out.println(tName+"不可重入"+new Date());
                // }
                try
                {
                    System.out.println(tName + "持有锁" + new Date());
                    sleep(6000);
                    System.out.println(tName + "做完了" + new Date());
                }
                finally
                {
                    dbInsertLock.unlock();
                    System.out.println(tName + "释放锁" + new Date());
                }
            }
            else
            {
                System.out.println(tName + "获取不到锁!再见" + new Date());
            }
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        super.run();
    }
}

 

附tryLock方法说明:

boolean tryLock(long time, 
TimeUnit unit) 
throws InterruptedException 
如果锁在给定的等待时间内空闲,并且当前线程未被中断,则获取锁。 
如果锁可用,则此方法将立即返回值 true。如果锁不可用,出于线程调度目的,将禁用当前线程,并且在发生以下三种情况之一前,该线程将一直处于休眠状态:

锁由当前线程获得;或者 
其他某个线程中断当前线程,并且支持对锁获取的中断;或者 
已超过指定的等待时间 
如果获得了锁,则返回值 true。

如果当前线程:

在进入此方法时已经设置了该线程的中断状态;或者 
在获取锁时被中断,并且支持对锁获取的中断, 
则将抛出 InterruptedException,并会清除当前线程的已中断状态。 
如果超过了指定的等待时间,则将返回值 false。如果 time 小于等于 0,该方法将完全不等待。

实现注意事项

在某些实现中可能无法中断锁获取,即使可能,该操作的开销也很大。程序员应该知道可能会发生这种情况。在这种情况下,该实现应该对此进行记录。

相对于普通方法返回而言,实现可能更喜欢响应某个中断,或者报告出现超时情况。

Lock 实现可能可以检测锁的错误用法,例如,某个调用可能导致死锁,在特定的环境中可能抛出(未经检查的)异常。该 Lock 实现必须对环境和异常类型进行记录。

参数: 
time - 等待锁的最长时间 
unit - time 参数的时间单位 
返回: 
如果获得了锁,则返回 true;如果在获取锁前超过了等待时间,则返回 false 
抛出: 
InterruptedException - 如果在获取锁时,当前线程被中断(并且支持对锁获取的中断)

展开阅读全文

实例化和具体化

08-22

大家好~!!rn我在看 C++ Primer Plus ,作者在介绍函数模板的显式实例化和显式具体化的时候,有下面这样的一句话:rn[img=https://img-bbs.csdn.net/upload/201308/22/1377114371_331099.png][/img]rnrn对句话不太理解,是不是不能像下面这样做?rn[code=c]template //templaternvoid foo(T t)rnrn cout << t << endl;rn return;rnrnrntemplate void foo(double); //Instantiationrnrntemplate <> void foo(double d) //Specializationrnrn cout << "this is " << d << endl;rnrnrnint main(int argv, char **argc)rnrn foo(1.0);rn return 0;rn[/code]rn上面的g++和VS都报错了:rng++:error: specialization of 'void foo(T) [with T = double]' after instantiationrnVS:error C2908: 显式专用化;已实例化“void foo(double)”rnrn按照g++的意思,难到instantiation放到specialization前面就可以了吗?rn[code=c]rntemplate //templaternvoid foo(T t)rnrn cout << t << endl;rn return;rnrnrntemplate <> void foo(double d) //Specializationrnrn cout << "this is " << d << endl;rnrnrntemplate void foo(double); //Instantiationrnrnint main(int argv, char **argc)rnrn foo(1.0);rn return 0;rnrn[/code]rn结果,g++确实不报错了,也没有警告,而VS依然报错:rnerror C3416: “foo”: 显式专用化可能无法显式实例化rnrn我想,那句话就是这个意思。而g++不报错,是不是因为模板函数在匹配类型的时候,具体化是优先于常规模板的,编译到Specialization的时候,找到匹配的了,然后就把Instantiation优化掉了??不作处理了??而且VS的错误信息有“可能”二字。。。rnrn这只是我的胡乱猜想,请大家多多指教! 谢谢!!rnrn 论坛

sqlserver *************,对一个表加解问题

11-03

[color=#FF0000]背景:[/color]rnrn一个表,本来是标值量函数生成ID(规则+自增的编号)作为主键(其他信息用户决定),rn这样只能一条一条地插入数据,没有问题rnrnrn[color=#FF0000]问题:[/color]rnrn现需要一次插入多条数据,放在存储过程中实现,这样,我用标值量函数获取一个ID(用一个变量@temp保存),rn作为主键,插入该条信息rn然后第二条数据在前一个ID(变量@temp)的基础上+1作为主键,插入该条信息,依次循环rn[color=#FF0000]rn问题就出在你第二个ID的取法上,假如存储过程执行期间,有其他用户对该表执行插入操作,rn你之前插入的那条数据放在存过过程中,存储过程开事物,在事物没有提交(完成本次插入数据操作)之前,rn别的用户去ID的话,调用标值量函数,标值量函数从这个表中取一个最大的ID+1返回,这时不就出现生成的ID重复了,问题就在这里[/color]rn[color=#FF0000]rn所以我想这个存储过程执行期间,在第一个ID生成后(调用标值量函数后),就把这个锁定,任何用户不允许读&&写本表数据rn但是不知道可行性,书上说sqlserver的锁机制不用用户显式地去控制,觉得对于常规的读写没问题,复杂一点的业务还是要去控制的,[/color]rnrnrn锁机制的知识掌握的不多,希望sql版的前辈们指点,给出点资源学习也行rnrn谢谢rnrn 论坛

没有更多推荐了,返回首页