三个窗口卖票的程序。
多线程共同操作一个对象的变量。锁是对象级别的,一个被synchronized修饰的代码块或方法一个时刻只能被一个线程执行。
package fire;
public class Seller1 extends Thread{
Ticket t = null;
public Seller1(Ticket t){
this.t=t;
}
public void run(){
int count=0;
for(int i=0;i<50;i++){
if(Ticket.tickets<=0)
break;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(t){
--Ticket.tickets;
if(Ticket.tickets>=0){
// System.out.println("剩余票数:"+Ticket.tickets+"张票"+" 窗口1卖出第"+Ticket.tickets+"张票");
System.out.println("剩余票数:"+(Ticket.tickets+1)+"张票 "+Thread.currentThread().getName()+"卖出第"+(Ticket.tickets+1)+"张票");
count++;
}
}
}
System.out.println("窗口1共卖出"+count+"张");
}
}
主类
package fire;
/**
* 三个窗口合作卖票程序
*
* 练习了Java的线程synchronized
* @author hp
*
*/
public class Ticket {
static int tickets=50;
public static void main(String[] args) {
Ticket t = new Ticket();
Seller1 s1 = new Seller1(t);
Seller1 s2 = new Seller1(t);
Seller1 s3 = new Seller1(t);
s1.setName("win1");
s2.setName("win2");
s3.setName("win3");
s1.start();
s2.start();
s3.start();
}
}
在kotlin语言中,没有了synchronized关键字,取而代之的是@Synchronized注解,
下面的例子是10人往一个账户里面存钱,使用注解实现的同步访问,保证数据的一致性。
package learn
class OkSync {
var money = 100
@Synchronized
fun doWhat() {
println("tid:${Thread.currentThread().id}")
}
@Synchronized
fun cunQian(add: Int) {
println("tid:${Thread.currentThread().id} now money is :$money, I will add ${add} money")
money += add
println("tid:${Thread.currentThread().id} after add the money is $money")
}
}
fun main() {
// println("hello android")
var o = OkSync()
// Thread {
o.doWhat()
// o.cunQian(20)
// }.start()
//
// Thread {
o.doWhat()
// o.cunQian(30)
// }.start()
for (i in 1..10) {
Thread {
if (i % 2 == 0) {
o.cunQian(30)
} else {
o.cunQian(20)
}
}.start()
}
}