synchronized同步代码块
一个线程访问一个对象中的synchronized(this)同步代码块时,其他试图访问该对象的线程将被阻塞
/**
* @company: 拓薪教育
* @author: 大亮老师 QQ:206229531
*/
public class Test1 {
public static void main(String[] args) {
Task t = new Task();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
}
/**
线程任务类
*/
static class Task implements Runnable{
@Override
public void run() {
//同步代码块
synchronized (this){
try {
//休眠一秒
TimeUnit.SECONDS.sleep(1);
//执行业务逻辑
System.out.println(Thread.currentThread().getName()+"正在执行...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
JUC中重入锁ReentrantLock实现同步锁
/**
* @company: 拓薪教育
* @author: 大亮老师 QQ:206229531
*/
public class Test2 {
/*
定义重入锁
*/
static Lock lock = new ReentrantLock();
public static void main(String[] args) {
Task t = new Task();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
t2.start();
}
/**
线程任务类
*/
static class Task implements Runnable{
@Override
public void run() {
//☆☆☆加锁☆☆☆
lock.lock();
try {
//休眠1秒
TimeUnit.SECONDS.sleep(1);
//执行业务逻辑
System.out.println(Thread.currentThread().getName()+"正在执行...");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//☆☆☆解锁☆☆☆
lock.unlock();
}
}
}
}
ReentrantLock和synchronized的不同
- Synchronized无法响应中断
- Synchronized无法得知是否获得到锁
- Synchronized无法控制锁超时处理
- 多线程读操作效率低
- 默认非公平锁,无法实现公平锁
我们可以看下面的例子,我们发现Synchronized是不能被中断的。
/**
* @company: 拓薪教育
* @author: 大亮老师 QQ:206229531
*/
public class Test3 {
//创建两个对象(锁)
static Object lock1 = new Object();
static Object lock2 = new Object();
static int flag = 1;
/**
* 定义线程实现类
*/
static class TxTask implements Runnable {
//标识属性
int flag;
//构造器
public TxTask(int flag) {
this.flag = flag;
}
@Override
public void run() {
//为了产生死锁通过flag来让两个线程进入不同分支
if (flag == 1) {
//持有锁1
synchronized (lock1) {
System.out.println("进入锁1");
//获得锁2
synchronized (lock2) {
System.out.println("进入锁1中的锁2");
}
}
} else {
//持有锁2
synchronized (lock2) {
System.out.println("进入锁2");
//获得锁1
synchronized (lock1) {
System.out.println("进入锁2中的锁1");
}
}
}
}
}
public static void main(String[] args) {
TxTask task = new TxTask(1);
TxTask task1 = new TxTask(0);
Thread t = new Thread(task);
Thread t1 = new Thread(task1);
t.start()