Java基础笔记34-synchronized(同步锁)关键字与Lock锁
1. synchronized 关键字
- 使用 synchronized 关键字 线程同步
- 关键词:synchronize 同步锁
- 语法:synchronize(锁){锁的内容}
- 要求:多个线程在操作时所用的锁是同一把锁
代码示例:
public class ThreadMethod1 {
public static void main(String[] args) {
// Ticket tic = new Ticket();
// //两个进程使用同一个对象
// Thread th1 = new Thread(tic,"窗口一");
// Thread th2 = new Thread(tic,"窗口二加急");
// th1.start();
// th2.start();
Object obj = new Object();
Ticket2 tic1 = new Ticket2(obj);
tic1.setName("窗口一");
tic1.start();
Ticket2 tic2 = new Ticket2(obj);
tic2.start();
}
}
/**
* 卖票,使用实现接口,
*/
class Ticket implements Runnable{
int tickets = 50;
@Override
public void run() {
// while(tickets>0) {
// System.out.println(Thread.currentThread().getName() + "剩余票数:" + (--tickets));
// }
//使用循环,进程循环进入
while(true) {
//同步锁,保证同时只能有一个进程执行循环体,以共同的唯一资源作为唯一锁,
synchronized(Ticket.class) {
//代码块执行条件
if(tickets>0) {
try {
//sleep()方法暂停当前进程,以免一个进程执行过快
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "剩余票数:" + (--tickets));
}else {
break;
}
}
}
}
}
/**
* 使用继承,
*
*/
class Ticket2 extends Thread{
//创建唯一锁
private Object obj;
private static int tickets = 100;
public Ticket2() {}
public Ticket2(Object obj) {
this.obj = obj;
}
@Override
public void run() {
while(true) {
synchronized(obj) {
if(tickets>0) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "剩余票数:" + (--tickets));
}else {
break;
}
}
}
}
}
2.Lock锁
- 使用 ReentrantLock 实现同步
- lock() 方法:上锁
- unlock() 方法:释放锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class LockDemo {
public static void main(String[] args) {
//创建锁对象
Lock lock = new ReentrantLock();
//创建要执行的任务
Ticket tic = new Ticket(lock);
//创建线程
Thread t1 = new Thread(tic,"窗口一");
Thread t2 = new Thread(tic);
//开启线程
t1.start();
t2.start();
}
}
class Ticket implements Runnable{
private int tickets = 100;
private Lock lock;
public Ticket(Lock lock) {
this.lock = lock;
}
@Override
public void run() {
while(true) {
//加锁
lock.lock();
if(tickets>0) {
try {
Thread.sleep(50);
System.out.println(Thread.currentThread().getName() + "剩余:" +(--tickets));
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
//释放锁
lock.unlock();
}
}else {
//lock.unlock();
break;
}
}
}
}
3.synchronized和Lock锁的区别
1、synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁
2、用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了
3、synchronized放弃锁只有两种情况:①线程执行完了同步代码块的内容②发生异常;而lock不同,它可以设定超时时间,也就是说他可以在获取锁时便设定超时时间,如果在你设定的时间内它还没有获取到锁,那么它会放弃获取锁然后响应放弃操作
版权声明:本文为w1226234212原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。