synchronized 到底锁的是谁?
修饰方法:
1、静态方法
2、非静态方法,锁住的是方法的调用者
修饰代码块
1、synchronized修饰非静态方法 锁住的是方法的调用者
锁住实例
流程:
1、线程A先拿到synModel对象然后给这个 synModel对象加上锁–接着等3s执行输出结束
2、线程B等1s后运行,此时 synModel对象 已经被 A拿到,所以他只能等待 等3s后,线程A释放 synModel对象,然后获取对象执行输出结束
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel.fun2();
},"B").start();
}
}
class SynModel{
public synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public synchronized void fun2(){
System.out.println("2...");
}
}
情况1 不会排队
注意:下面这种情况是不会排队的,因为锁的是实例。
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel1 = new SynModel();
SynModel synModel2 = new SynModel();
new Thread(()->{
synModel1.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel2.fun2();
},"B").start();
}
}
class SynModel{
public synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public synchronized void fun2(){
System.out.println("2...");
}
}
2 、修饰静态方法
只是把SynModel中的方法变成了静态的,注意此时锁住的是 SynModel这个类,不是锁的实例。会排队 先输出1后输出2
public class SynchronizedTest {
public static void main(String[] args) throws InterruptedException {
SynModel synModel1 = new SynModel();
SynModel synModel2 = new SynModel();
new Thread(()->{
synModel1.fun1();
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
synModel2.fun2();
},"B").start();
}
}
class SynModel{
public static synchronized void fun1() {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("1...");
}
public static synchronized void fun2(){
System.out.println("2...");
}
}
3、代码块
synchronized (this){}
锁住的是SynModel这个对象。可以看到循环的五次都是同一个SynModel对象。所以五个线程 某个时刻只能有一个线程拿到这个SynModel对象 这个资源。
每个线程会依次输出start end
public class SynchronizedTest {
public static void main(String[] args) {
final SynModel synModel = new SynModel();
for (int i = 0; i < 5; i++) {
synModel.fun3();
}
}
}
class SynModel{
public void fun3(){
synchronized (this){
System.out.println("start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("end");
}
}
}
如果把对象放在循环里面,此时就是五个线程拿五个资源了。并没有去争夺资源文章来源:https://www.toymoban.com/news/detail-745788.html
public class SynchronizedTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun3();
}).start();
}
}
}
class SynModel{
public void fun3(){
synchronized (this){
System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
}
}
}
锁住SynModel.class 此时五个线程就会竞争,因为锁住的是 SynModel这个类,而不是实例对象了。文章来源地址https://www.toymoban.com/news/detail-745788.html
public class SynchronizedTest {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
final SynModel synModel = new SynModel();
new Thread(()->{
synModel.fun3();
}).start();
}
}
}
class SynModel{
public void fun3(){
synchronized (SynModel.class){// this SynModel.class
System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
}
}
}
到了这里,关于synchronized 到底锁的是谁?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!