Java线程-用代码同步实现对代码的加锁
方式1. 同步代码块;
方式2. 同步方法;
用第一种方式实现代码同步加锁:
package com.mldn;
class ThreadSyn implements Runnable
{
private int ticket = 5; // 一共仅有5张票
public void run() // 进行卖票操作
{
for (int i = 0; i < 50; i++) // 循环50次,确保ticket卖完
{
synchronized (this) // 表示对当前对象加锁,只允许被锁定的对象执行该代码块中的代码,当前对象永远是最先抢得CPU调度的那个线程体!
{
if (this.ticket > 0)
{
System.out.println(Thread.currentThread().getName() + “判断完毕,ticket = ” + this.ticket + “确认还有票,将进行卖票操作!”);
try
{
Thread.sleep(2000); // 延迟操作2秒,使判断 与 操作 之间产生明显的延迟
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + “正在卖票: ticket = ” + this.ticket–);
}
}
}
}
}
public class SynLater
{
public static void main(String[] args)
{
ThreadSyn th = new ThreadSyn();
new Thread(th, “票贩子A”).start();
new Thread(th, “票贩子B”).start();
new Thread(th, “票贩子C”).start();
}
}
/*第一次运行java命令,C线程获得同步锁:
administrator@xu-desktop:~$ javac -d . work/SynLater.java
administrator@xu-desktop:~$ java com.mldn.SynLater
票贩子C判断完毕,ticket = 1确认还有票,将进行卖票操作!
票贩子C正在卖票: ticket = 5
票贩子C判断完毕,ticket = 2确认还有票,将进行卖票操作!
票贩子C正在卖票: ticket = 4
票贩子C判断完毕,ticket = 3确认还有票,将进行卖票操作!
票贩子C正在卖票: ticket = 3
票贩子C判断完毕,ticket = 4确认还有票,将进行卖票操作!
票贩子C正在卖票: ticket = 2
票贩子C判断完毕,ticket = 5确认还有票,将进行卖票操作!
票贩子C正在卖票: ticket = 1
第二次运行java命令,A线程获得同步锁:
administrator@xu-desktop:~$ java com.mldn.SynLater
票贩子A判断完毕,ticket = 1确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 5
票贩子A判断完毕,ticket = 2确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 4
票贩子A判断完毕,ticket = 3确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 3
票贩子A判断完毕,ticket = 4确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 2
票贩子A判断完毕,ticket = 5确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 1
可见,对产生延迟的判断和修改加了同步锁以后,只有抢先获得该锁的线程才有权限执行加锁(同步代码块)的代码,也就产生了上面
的运行现象: 每次延迟都只有一个线程进行了判断或修改操作,并且永远是那个获得了权限的线程;
*/
——-用方式2.同步方法可实现同样的效果:
package com.mldn;
class ThreadSyn implements Runnable
{
private int ticket = 5; // 一共仅有5张票
public void run() // 进行卖票操作
{
for (int i = 0; i < 50; i++) // 循环50次,确保ticket卖完
{
this.sale(); // 调用同步方法
}
}
public synchronized void sale() // 同步方法,实现对要同步代码加锁
{
if (this.ticket > 0)
{
System.out.println(Thread.currentThread().getName() + “判断完毕,ticket = ” + this.ticket + “确认还有票,将进行卖票操作!”);
try
{
Thread.sleep(2000); // 延迟操作2秒,使判断 与 操作 之间产生明显的延迟
}
catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + “正在卖票: ticket = ” + this.ticket–);
}
}
}
public class SynLater
{
public static void main(String[] args)
{
ThreadSyn th = new ThreadSyn();
new Thread(th, “票贩子A”).start();
new Thread(th, “票贩子B”).start();
new Thread(th, “票贩子C”).start();
}
}
/*第一次运行java命令,A线程获得同步锁:
administrator@xu-desktop:~$ java com.mldn.SynLater
票贩子A判断完毕,ticket = 5确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 5
票贩子A判断完毕,ticket = 4确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 4
票贩子A判断完毕,ticket = 3确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 3
票贩子A判断完毕,ticket = 2确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 2
票贩子A判断完毕,ticket = 1确认还有票,将进行卖票操作!
票贩子A正在卖票: ticket = 1
*/
声明: 除非转自他站(如有侵权,请联系处理)外,本文采用 BY-NC-SA 协议进行授权 | 嗅谱网
转载请注明:转自《Java线程-用代码同步实现对代码的加锁》
本文地址:http://www.xiupu.net/archives-73.html
关注公众号:
微信赞赏
支付宝赞赏