java 多线程
synchronized关键字
方法或代码块的互斥性来完成实际上的一个原子操作。(方法或代码块在被一个线程调用时,其他线程处于等待状态)
所有的Java对象都有一个与synchronzied关联的监视器对象(monitor),允许线程在该监视器对象上进行加锁和解锁操作。
a、静态方法:Java类对应的Class类的对象所关联的监视器对象。
b、实例方法:当前对象实例所关联的监视器对象。
c、代码块:代码块声明中的对象所关联的监视器对象。
所以多线程操作同一个内容并要保持一致性时,就将该对象设为类的静态成员
public class syncTest {
public static int count = 0;
public static synchronized void addC(){
if(count <100){
count ++;
System.out.println(Thread.currentThread().getName() +" "+count);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String args[]){
Thread thread1 = new Thread();
thread1 = new Thread(new Runnable(){
public void run(){
System.out.println("thread1 start run");
while(count <100){
syncTest.addC();
}
}
});
syncTest st = new syncTest();
Thread thread2 = new Thread();
thread2 = new Thread(new Runnable(){
public void run(){
System.out.println("thread2 start run");
while(count <100){
st.addC();
}
}
});
thread1.start();
thread2.start();
}
}
输出:

可以看到,两个线程操作的是同一个数
LOCK:
synchronized的缺陷:
当一个线程获取了锁并执行该代码,其他线程便只能一直等待,等待该线程释放锁。而释放锁有两种情况:
- 获取锁的线程执行完了该代码块
- 线程执行发生异常,此时JVM会让线程自动释放锁
lock与synchronized的区别:
- Lock不是Java语言内置的,synchronized的是Java的关键字,是内置特性。Lock是一个类,通过这个类可以实现同步访问。
- Lock和synchronized有一点非常大的不同,采用synchronized不需要用户手动释放锁,当synchronized方法或者synchronized代码块执行完后,系统会自动让新县城释放对锁的占用。而lock必须要用户去手动释放。
获取lock的方式: lock(), trylock(), trylock(long time, timeout unit)和 lockInterrutibly()
对锁操作使用try{}catch{},释放的操作放在finnally{}中
Lock lock = …
Lock.lock()
Try{
}catch(Exception e){
}
Finnally{
Lock.unlock();
}
Lock.lock()获取锁
Lock.tryLock()尝试获取锁,如果成功则返回true,失败则返回false
Lock.tryLock(long time, TimeUnit unit) 拿不到锁会等待一段时间,如果期限内拿不到则返回false
Lock.lockInterruptibly()
当通过这个方法去获取锁时,如果线程正在等待获取锁,则这个线程能够响应中断,即中断线程的等待状态。也就使说,当两个线程同时通过lock.lockInterruptibly()想获取某个锁时,假若此时线程A获取到了锁,而线程B只有在等待,那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。
由于lockInterruptibly()的声明中抛出了异常,所以lock.lockInterruptibly()必须放在try块中或者在调用lockInterruptibly()的方法外声明抛出InterruptedException。
浙公网安备 33010602011771号