欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  Java

Java:详细讲解对象锁“synchronized”与全局锁

程序员文章站 2022-04-27 09:09:23
...
先来看一段代码:
class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			System.out.println(Thread.currentThread().getName() + "开始执行");
			System.out.println("count还剩" + --count);
			System.out.println(Thread.currentThread().getName() + "执行结束");
			System.out.println();
		}
	}	
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

运行结果如下:

Thread-0开始执行
Thread-2开始执行
Thread-1开始执行
count还剩8
count还剩9
Thread-2执行结束
count还剩7
Thread-1执行结束

Thread-1开始执行

Thread-0执行结束

Thread-0开始执行
count还剩5
Thread-0执行结束

Thread-2开始执行
count还剩4
Thread-2执行结束

Thread-2开始执行
count还剩3
count还剩6
Thread-2执行结束

Thread-2开始执行
Thread-0开始执行
count还剩2
Thread-2执行结束

Thread-2开始执行
count还剩0
Thread-2执行结束

Thread-1执行结束

count还剩1
Thread-0执行结束

很显然这并不是我们想要的结果,我们想要的结果是:一个独自完整地按顺序跑完自己的run()方法,然而上面的结果是乱序的:上一个线程还没有跑完自己的任务,第二个线程就进来了。那么如何来解决这个问题呢?

首先我们来分析一下,三个线程同时拿到我们自己创建的对象myThread,然后启动这三个线程,这三个线程会同时进入这个run()方法进行执行。如果我们想要每一个线程进入后完整的跑完自己的任务,这时候就需要把这个myThread对象锁起来,不让其他线程拿到,这样就能实现。就比如说,有一个房间,你进入之后,不想要其他人再进来,你就得把门锁住一个道理。

在Java里面为我们提供了一个叫做“synchronized”的锁子。那么它应该怎样来使用呢?

“synchronized”的两种模式:同步方法、同步代码块。

一、对象锁:

1、同步代码块:在代码块前面加上synchronized(要锁的对象)。

class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		synchronized (this) {
			while(count > 0) {
				System.out.println(Thread.currentThread().getName() + "开始执行");
				System.out.println("count还剩" + --count);
				System.out.println(Thread.currentThread().getName() + "执行结束");
				System.out.println();
			}
		}	
	}	
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

2、同步方法:在方法的返回值前面加上synchronized关键字。

class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			count--;
			fun();
		}
	}
	public synchronized void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

二、全局锁:

在上面,我们锁住的都是myThread对象,如果要锁住多个对象的同一个方法又该怎么办呢?

这里与对象锁也有两种方法:同步方法和同步代码块。

1、同步代码块前的括号里写成想要锁住的方法的类.class

class MyThread implements Runnable{
	private static int count = 10;
	@Override
	public void run() {
		synchronized (MyThread.class) {
			while(count > 0) {
				count--;
				fun();
			}
		}	
	}
	public void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

2、在前面所说同步方法的基础上,加上static关键字,就可以实现全局锁。

class MyThread implements Runnable{
	private static int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			fun();
		}
	}
	public synchronized static void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
		count--;
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

相关文章:

Java同步锁(synchronized)的示例代码分享

详解Java中synchronized关键字的死锁和内存占用问题

相关视频:

全面解析Java注解

以上就是Java:详细讲解对象锁“synchronized”与全局锁的详细内容,更多请关注其它相关文章!