北京市网站开发/关键词app
用于解决多线程安全问题的方式:
1. 同步代码块 (隐式锁)
2. 同步方法(隐式锁)
3. 同步锁 Lock( jdk 1.5 后)
注意:是一个显示锁,需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁
下面举一个售票例子:
1)同步代码块
package com.lxj.juc;public class TestSync {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(ticket).start();new Thread(ticket).start();new Thread(ticket).start();}}
class Ticket implements Runnable{private int ticket = 100;@Overridepublic void run() {while(true) {synchronized(this) { //this代表对当前对象上锁if(ticket > 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" : 购票成功,余票为:" + --ticket );}else {break;}}}}}
运行结果:
Thread-0 : 购票成功,余票为:99
Thread-0 : 购票成功,余票为:98
Thread-2 : 购票成功,余票为:97
.....
Thread-2 : 购票成功,余票为:7
Thread-0 : 购票成功,余票为:6
Thread-0 : 购票成功,余票为:5
Thread-1 : 购票成功,余票为:4
Thread-1 : 购票成功,余票为:3
Thread-0 : 购票成功,余票为:2
Thread-0 : 购票成功,余票为:1
Thread-2 : 购票成功,余票为:0
2)同步方法
package com.lxj.juc;public class TestSync {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(ticket).start();new Thread(ticket).start();new Thread(ticket).start();}}class Ticket implements Runnable {private int ticket = 100;@Overridepublic void run() {while (true) {if (ticket > 0) {int i = purchase();if(i == 0) {break;}}else {break;}}}private synchronized int purchase() {if (ticket > 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " : 购票成功,余票为:" + --ticket);}else {return 0;}return 1;}}
运行结果:
Thread-0 : 购票成功,余票为:99
Thread-0 : 购票成功,余票为:98
Thread-0 : 购票成功,余票为:97
Thread-2 : 购票成功,余票为:96
Thread-1 : 购票成功,余票为:95
....
Thread-1 : 购票成功,余票为:8
Thread-2 : 购票成功,余票为:7
Thread-2 : 购票成功,余票为:6
Thread-0 : 购票成功,余票为:5
Thread-0 : 购票成功,余票为:4
Thread-0 : 购票成功,余票为:3
Thread-2 : 购票成功,余票为:2
Thread-1 : 购票成功,余票为:1
Thread-2 : 购票成功,余票为:0
3)同步锁lock
package com.lxj.juc;import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class TestSync {public static void main(String[] args) {Ticket ticket = new Ticket();new Thread(ticket).start();new Thread(ticket).start();new Thread(ticket).start();}}class Ticket implements Runnable {private int ticket = 100;private Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {lock.lock(); //上锁try {if (ticket > 0) {try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + " : 购票成功,余票为:" + --ticket);}else {break;}} finally {lock.unlock(); //解锁}}}}
运行结果:
Thread-0 : 购票成功,余票为:99
Thread-1 : 购票成功,余票为:98
Thread-1 : 购票成功,余票为:97
Thread-1 : 购票成功,余票为:96
Thread-1 : 购票成功,余票为:95
Thread-2 : 购票成功,余票为:94
......
Thread-0 : 购票成功,余票为:6
Thread-0 : 购票成功,余票为:5
Thread-1 : 购票成功,余票为:4
Thread-2 : 购票成功,余票为:3
Thread-2 : 购票成功,余票为:2
Thread-2 : 购票成功,余票为:1
Thread-2 : 购票成功,余票为:0
注意使用同步锁一定要记得关闭锁,放在try{}finally{}中。