/*
* 卖票:同时两个窗口卖票
使用Runnable方法来实现多线程;
package Threadsenior;
import java.util.ArrayList;
public class TicketService {
private ArrayList<String> all;
public TicketService(){
all = new ArrayList<String>();
all.add("01车01A");
all.add("01车01B");
all.add("01车01C");
all.add("01车01D");
all.add("01车01F");
all.add("02车02A");
all.add("02车02B");
all.add("02车02C");
all.add("02车02D");
all.add("02车02F");
}
//查询是否还有余票
public boolean hasTicket(){
return all.size()>0;
}
//卖票
public String sale(){
return all.remove(0);
}
}
public class TestTicketRunnable {
public static void main(String[] args) {
@SuppressWarnings("unused")
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my,"窗口一");
Thread t2 = new Thread(my,"窗口二");
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable{
private TicketService ts = new TicketService();
public void run(){
while(true){
synchronized(ts){
if(ts.hasTicket()){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sells "+ts.sale());
}else{
break;
}
}
}
}
}
运行结果如下:
窗口一 sells 01车01A
窗口二 sells 01车01B
窗口一 sells 01车01C
窗口二 sells 01车01D
窗口二 sells 01车01F
窗口二 sells 02车02A
窗口一 sells 02车02B
窗口一 sells 02车02C
窗口二 sells 02车02D
窗口一 sells 02车02F
* 继承和实现接口的方式的区别
* 1、共享数据
* thread必须用static的方式,
* runnable只需要用一个对象就可以
*
* 2、选择对象时,比较方便
* runnable可以直接用this对象,继承thread的方式不能用this
*
* 3、继承有单继承限制,实现没有限制
*
* 开发中尽量面向接口编程
为提高代码的可读性,将同步部分的代码封装起来
*3、两种方式
*(1)同步代码块
*语法格式
*synchronized(同步的锁对象){
* 需要锁起来的代码:一个线程在运行这段代码期间,不想别的线程插入进来
*}
public class TestTicket {
public static void main(String[] args) {
TicketSaler t1 = new TicketSaler("窗口一");
TicketSaler t2 = new TicketSaler("窗口二");
t1.start();
t2.start();
}
}
class TicketSaler extends Thread{
private static TicketService ts = new TicketService();//多卖了一张票
private String name;
public TicketSaler(String name) {
super(name);
}
public void run(){
while(true){
if(ts.hasTicket()){
saleOneticket();
}else{
break;
}
}
}
public synchronized static void saleOneticket(){//继承的方式,采用静态方法,考量this是否可用,因为这里采用的是继承的方法,所以在这里this不合适
if(ts.hasTicket()){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" sell "+ts.sale());
}
}
}
*(2)同步方法
* 如果你的一次任务是在一个方法中完成的,那么可以可以锁一个方法
* 语法格式
* 【修饰符】 synchronized 返回值类型 方法名 (【形参列表】) 【throws 异常列表】
*
* 同步方法的锁对象
* 费静态方法:this 考量这个this是否可以做为锁对象
* 静态方法 :当前类的class
* 每一个类型被加载内存中后都会生成一个Class对象来表示这个类型,
* 只要是同一种类型,Class对象就是同一个
public class TestTicketRunnable {
public static void main(String[] args) {
@SuppressWarnings("unused")
MyRunnable my = new MyRunnable();
Thread t1 = new Thread(my,"窗口一");
Thread t2 = new Thread(my,"窗口二");
t1.start();
t2.start();
}
}
class MyRunnable implements Runnable{
private TicketService ts = new TicketService();
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(ts.hasTicket()){
saleOneticket();
}else{
break;
}
}
}
public synchronized void saleOneticket(){
if(ts.hasTicket()){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" "//
+ "sells "+ts.sale());
}
}
}