同步代码块:
synchronized(object) {}
其中object为我们使用的同步锁,对于继承的方式,使用this或者创建一个非静态对象作为锁是无用的,无法阻止错误数据的产生。所以我们使用static的对象
同步方法:
public synchronized void method() {}
由于同步方法的锁使用的是this,当前对象,所以也是无法起效果的。所以在继承中,是不能使用同步方法操作共享数据的。代码:
继承
在这里我们使用的是 static类型的obj对象为锁的同步代码块,避免了错误数据大帝问题。
package com.atguigu.Thread;
public class TicketDemo2 {
public static void main(String[] args) {
Ticket1 t1 = new Ticket1();
Ticket1 t2 = new Ticket1();
Ticket1 t3 = new Ticket1();
t1.setName("t1窗口");
t2.setName("t2窗口");
t3.setName("t3窗口");
t1.start();
t2.start();
t3.start();
}
}
class Ticket1 extends Thread {
static int tick = 100;
static Object obj = new Object();
@Override
public void run() {
while(true) {
synchronized(obj) {
if(tick>0){
try {
Thread.currentThread().sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"售出车票,ticket号为:"+ tick--);
}else {
break;
}
}
}
}
}
实现:
在这里由于三个线程使用一个对象,所以我们可以使用this作为锁
<span style="font-size:14px;">package com.atguigu.Thread;
public class TicketDemo3 {
public static void main(String[] args) {
TicketTest t = new TicketTest();
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();
}
}
class TicketTest implements Runnable {
private int tick = 100;
public void run() {
while (true) {
// synchronized (this) {
// if (tick > 0) {
// System.out.println(Thread.currentThread().getName()
// + "售出车票,tick号为:" + tick--);
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// } else
// break;
sale();
}
}
public synchronized void sale() {
if (tick > 0) {
System.out.println(Thread.currentThread().getName()
+ "售出车票,tick号为:" + tick--);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
</span><span style="font-size:24px;">
}
</span>