package cn.sasa.demo3; import java.util.concurrent.ExecutionException; public class ThreadDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
//创建Runnable接口实现类对象
Ticket t = new Ticket();
//创建3个Thread类对象,传递Runnable接口实现类
Thread t0 = new Thread(t);
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t); t0.start();
t1.start();
t2.start();
t3.start();
/**
* 线程安全问题一般发生在:
* 多线程并发访问同一个数据资源
*
* 通过线程休眠,发现了安全问题
*
* 解决安全问题:
* ------------------------------------ 方式一------------------------------
* 同步代码块
* synchronized(任意对象){
* 线程要操作的共享数据
* }
* 同步代码块中的锁对象可以是任意对象,
* 但多线程时,要使用同一个锁对象才能够保证线程安全性
*
* ------------------------------------ 方式二------------------------------
* 同步方法 在方法声明上加入同步关键字
* eg :
* private synchronized void func(){
* ...
* }
* 同步方法中的对象锁,是本类对象引用 this
* 如果方法是静态的,锁是本类.class属性
*
* ------------------------------------ 方式三------------------------------
* jdk 1.5之后 Lock接口
* private Lock lock = new ReentrantLock();
* lock.lock();
* lock.unlock();
*/ }
}
package cn.sasa.demo3; import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class Ticket implements Runnable {
//定义出售的票源
private int ticket = 100; //jdk 1.5之后 可用接口Lock 创建锁对象
private Lock lock = new ReentrantLock(); public void run(){
int flag = 100;
while(flag > 0){
//获取锁
lock.lock();
buyTickets();
//释放锁
lock.unlock();
flag --;
}
} private void buyTickets() {
if( ticket > 0){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" 出售第 "+ticket--);
}
}
}