//【注意】:何时需要线程同步:1.有共享数据;2.对共享数据有写的操作;3.多线程环境
//例一:模拟银行取款,对同一账户两个人一个通过ATM一个通过人工同时取款,此时相当于两个线程,那么此时对同一共享数据余额有写的操作,且是多线程则需要使用线程同步,见代码:
package ThreadTest;
class Picket{
private double num;
public void setNum(double n){
this.num = n;
}
public double getNum(){
return this.num;
}
public void withdraw(double m){
this.setNum(this.getNum() - m);
}
}
class Processor11 implements Runnable{
public int cnt = 1000;
public Picket p;
public Processor11(Picket p1){
p1.setNum(1000);
p = p1;
}
@Override
public void run() {
synchronized(this){
p.withdraw(100);
cnt -= 100;
System.out.println(Thread.currentThread().getName() + "当前余额-->" + cnt);
}
}
}
public class ThreadTest11 {
public static void main(String[] args) throws InterruptedException {
Picket p = new Picket();
Processor11 pro = new Processor11(p);
Thread t1 = new Thread(pro, "t1");
Thread t2 = new Thread(pro, "t2");
t1.start();
t2.start();
}
}
运行截图:
//例二:这是一个模拟火车票的发售窗口,此时有两个窗口对火车票进行发售,那么此时有共享数据火车票总数,两个窗口多线程,每售出一张对共享数据有写的操作,则此时要线程同步,见代码:
package ThreadTest;
class Thread02 implements Runnable{
private static int countTicket = 100;
@Override
public void run() {
while(countTicket>0){
sale1();
}
}
public void sale1(){
synchronized(this){
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
if(countTicket>0){ //------当把这个if判断去掉 最后还是会有两个线程来争夺最后一张票 会挨个执行,数据不会出错,但是逻辑会出错。
System.out.println("当前线程名字:"+Thread.currentThread().getName()+";出售第"+(100 - countTicket + 1)+"张票。");
countTicket--;
}
}
}
}
public class ThreadTest11 {
public static void main(String[] args) throws InterruptedException {
Thread02 t = new Thread02();
Thread t1 = new Thread(t,"窗口1");
Thread t2 = new Thread(t,"窗口2");
t1.start();
t2.start();
}
}
运行部分截图: