卖票的问题 : 错票 ,重票
问题的原因 : 多个线程同时操作共享数据,当其中一个线程正在执行操作共享数据的代码时,其它的线程也进入了。
解决问题的方案 : 多个线程同时操作共享数据,只允许同时只有一个线程 对共享数据进行操作
方式一 : 同步代码块
格式 : synchronized (监视器) {
操作共享数据的代码;
}
1.监视器可以是任意类的对象 (多个线程必须保证是同一把锁)
方式二 :同步方法
public synchronized boolean tick(){
操作共享数据的代码;
}
注意:如果是在继承Thread中使用同步方法 必须给同步方法加static
继承Thread和实现Runnable的区别?
1.单继承多实现
2.共享数据在Thread中需要用static修饰 ,在Runnable中不需要用static修饰
3.监视器(同步锁)在Thread中不能使用this,在Runnable中可以使用this
4.同步方法在Thread中需要使用static进行修饰,在Runnable中不需要。
public class ThreadTest {
public static void main(String[] args) {
// MyRun2 m = new MyRun2();
//
// Thread t1 = new Thread(m);
// Thread t2 = new Thread(m);
// Thread t3 = new Thread(m);
//
// t1.setName("窗口1--------");
// t2.setName("窗口2--------");
// t3.setName("窗口3--------");
//
// t1.start();
// t2.start();
// t3.start();
// System.out.println("-------------------------------------");
MyThread2 t1 = new MyThread2();
MyThread2 t2 = new MyThread2();
MyThread2 t3 = new MyThread2();
t1.setName("窗口1--------");
t2.setName("窗口2--------");
t3.setName("窗口3--------");
t1.start();
t2.start();
t3.start();
}
}
/*
* 在继承Runnable接口中 使用同步方法 实现同步安全问题
*/
class MyRun2 implements Runnable {
private int tick = 100;
@Override
public void run() {
while (true) {
boolean b = tick();
if(!b){
return;
}
}
}
/*
* 同步方法
* 默认的锁是 this
*/
public synchronized boolean tick(){
if (tick > 0) {
try {
Thread.currentThread().sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + tick);
tick--;
return true;
} else {
return false;
}
}
}
/*
* 在继承Thread中 使用同步方法 实现同步安全问题
*/
class MyThread2 extends Thread {
private static int tick = 100;
private static Object obj = new Object();
@Override
public void run() {
while (true) {
boolean b = tick();
if(!b){
return;
}
}
}
/*
* 同步方法
* 默认的锁是 : 当前类的运行时类的对象 MyThread2.class
*/
public static synchronized boolean tick(){
if (tick > 0) {
try {
Thread.currentThread().sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + tick);
tick--;
return true;
} else {
return false;
}
}
}