先来看一段代码:
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还剩8count还剩9thread-2执行结束count还剩7thread-1执行结束thread-1开始执行thread-0执行结束thread-0开始执行count还剩5thread-0执行结束thread-2开始执行count还剩4thread-2执行结束thread-2开始执行count还剩3count还剩6thread-2执行结束thread-2开始执行thread-0开始执行count还剩2thread-2执行结束thread-2开始执行count还剩0thread-2执行结束thread-1执行结束count还剩1thread-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”与全局锁的详细内容。
