CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

JavaSE进阶线程的同步-源码交易平台丞旭猿

问题的提出

1、多个线程执行的不确定性引起执行结果的不稳定。

2、多个线程对账本的共享,会造成操作的不完整性,会破坏数据。

例 题

模拟火车站售票程序,开启三个窗口售票。

class Ticket implements Runnable {private int tick = 100;public void run(){while (true) {if (tick > 0) {System.out.println(Thread.currentThread().getName() + "售出车票,tick号为:" + tick--);} elsebreak;}}}class TicketDemo {public static void main(String[] args) {Ticket t = new Ticket();Thread t1 = new Thread(t);Thread t2 = new Thread(t);Thread t3 = new Thread(t);t1.setName("t1窗口");t2.setName("t2窗口");t3.setName("t3窗口");t1.start();t2.start();t3.start();}}
private int tick = 100;public void run() {while (true) {if (tick > 0) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "售出车票,tick号为:" + tick--);}}}

1) 多线程出现了安全问题

2)问题的原因:

当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,另一个线程参与进来执行。导致共享数据的错误。

3)解决办法

对多条操作共享数据的语句,只能让一个线程都执行完,在执行过程中,其他线程不可以参与执行。

Synchronized的使用方法

lJava对于多线程的安全问题提供了专业的解决方式:同步代码块

1)synchronized (对象){

// 需要被同步的代码;

}

2)synchronized还可以放在方法声明中,表示整个方法

为同步方法。

例如:

public synchronized void show (String name){

….

}

同步锁(Lock)

从Java 5开始,Java提供了更强大的线程同步机制——通过显式定义同步锁对象来实现同步。同步锁使用Lock对象充当。

Lock是控制多个线程对共享资源进行访问的工具。锁提供了对共享资源的独占访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得Lock对象。

在实现线程安全的控制中,比较常用的是ReentrantLock(可重入锁),可以显式加锁、释放锁。

class A {private final ReentrantLock lock = new ReenTrantLock();public void m() {lock.lock();try {// 保证线程安全的代码;} finally {lock.unlock();}}}

互斥锁

l 在Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。

1、每个对象都对应于一个可称为互斥锁的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象

2、关键字synchronized 来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。

3、 同步的局限性:导致程序的执行效率要降低

同步方法(非静态的)的锁为this。

同步方法(静态的)的锁为当前类本身。

class Singleton {private static Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}public class TestSingleton {public static void main(String[] args) {Singleton s1 = Singleton.getInstance();Singleton s2 = Singleton.getInstance();System.out.println(s1 == s2);}}

小结:释放锁的操作

1、当前线程的同步方法、同步代码块执行结束

2、当前线程在同步代码块、同步方法中遇到break、return终止了该代码块、该方法的继续执行。

3、当前线程在同步代码块、同步方法中出现了未处理的Error或Exception,导致异常结束

4、当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁。

线程的死锁问题

l 死锁

不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁

l 解决方法

1、专门的算法、原则

2、尽量减少同步资源的定义

public class TestDeadLock {public static void main(String[] args) {final StringBuffer s1 = new StringBuffer();final StringBuffer s2 = new StringBuffer();new Thread() {public void run() {synchronized (s1) {s2.append("A");synchronized (s2) {s2.append("B");System.out.print(s1);System.out.print(s2);}}}}.start();new Thread() {public void run() {synchronized (s2) {s2.append("C");synchronized (s1) {s1.append("D");System.out.print(s2);System.out.print(s1);}}}}.start();}}
举报/反馈

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容