runnable实习多线程的练习
class MyRunable implements Runnable {
private int ticket = 1000;
//private Object obj = new Object();
@Override
public void run() {
while (true) {
if(!show()) {
break;
};
}
}
private synchronized boolean show() {//同步监视器就是:this
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "票号:" + ticket);
ticket--;
return true;
}
return false;
}
}
/**
* 例子 :创建三个窗口卖票,票总数100 使用实现Runable的方式
*
* 1、卖票过程中出现了重票和错票==》出现了线程安全问题
* 2、问题出现的原因:当某个线程操作车票的过程中,尚未操作完成时,其它线程参与进来,也操作车票。(车票是共享数据)
* 3、如何解决:当一个线程a在操作ticket的时候,其它线程不能参与进来。直到线程a操作完ticket时,其它线程才可以操作ticket。
* 这种情况即使a出现了阻塞,也不能被改变。 4、在java中,我们通过同步机制,来解决线程安全的问题。 方法一:同步代码块 synchronized
* (MyRunable.class 同步监视器) { //需要被同步的代码 } 说明:
* 1、操作共享数据的代码,即为需要被同步的代码。--》范围要精确,范围过大会降低性能
* 2、共享数据:多个线程共同操作的变量。比如ticket就是共享数据
* 3、同步监视器,俗称锁。任何一一个类的对象,都可以充当锁
*
* 补充:使用实现Runable接口的方式时可以考虑,使用shis替代共享锁(synchronized (this))
*
* 要求:多个线程必须要有同一把锁,也就是这个锁对象在线程中只new一次
*
* 方法二:同步方法
* 如果操作的共享数据的代码完整的声明在一个方法中我们不妨将此方法声明同步
*
* @author Administrator
*
*/
public class WindowsRunable {
public static void main(String[] args) {
//此时MyRunable只创建了一次,满足线程之间共享一个对象锁
MyRunable myRunable = new MyRunable();
Thread myt1 = new Thread(myRunable);
Thread myt2 = new Thread(myRunable);
Thread myt3 = new Thread(myRunable);
myt1.setName("窗口1");
myt2.setName("窗口2");
myt3.setName("窗口3");
myt1.start();
myt2.start();
myt3.start();
}
}