多线程例子 — 窗口卖票
多线程的创建--窗口买票两种实现方式
创建多线程方法一: 同步代码块实现Runnable接口
1. 创建一个实现了Runnable接口的类
2. 实现类去实现Runnable中的抽象方法
3. 创建实现类的对象
4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象
5. 通过Thread类的对象调用start()
public class ThreadTest1 { public static void main(String[] args) { //创建实现类的对象 MThead mThead = new MThead(); //将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象 Thread t1 = new Thread(mThead); //通过Thread类的对象调用start(): 1.启动线程 2.调用当前线程的run()-->调用了Runnable类型的target() t1.setName("线程1"); t1.start(); Thread t2 = new Thread(mThead); t2.setName("线程2"); t2.start(); Thread t3 = new Thread(mThead); t3.setName("线程3"); t3.start(); } } class MThead implements Runnable{ private static int ticket = 100; //多个线程共享一个静态变量 Object object = new Object(); //锁 任意一个类的对象 多个线程必须使用同一个锁 也可以用this @Override public void run(){ while (true){ synchronized(object){ //也可以用this // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } if (ticket>0){ System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket); ticket--; }else { break; } } } } }
创建多线程方法二: 同步方法实现Runnable接口
如果操作共享数据的代码完整的声明在一个方法中,不妨将此方法声明同步的
public class tongbuRunnable { public static void main(String[] args) { //创建实现类的对象 MThead mThead = new MThead(); //将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象 Thread t1 = new Thread(mThead); Thread t2 = new Thread(mThead); Thread t3 = new Thread(mThead); //通过Thread类的对象调用start(): 1.启动线程 2.调用当前线程的run()-->调用了Runnable类型的target() t1.setName("线程1"); t2.setName("线程2"); t3.setName("线程3"); t1.start(); t2.start(); t3.start(); } } class MyThead implements Runnable{ private static int ticket = 100; //多个线程共享一个静态变量 @Override public void run(){ while (true){ show(); } } public synchronized void show(){ //同步监视器默认为this if (ticket>0){ System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket); ticket--; } } }
创建多线程方法三: 同步代码块继承Thread方式
1. 创建一个继承Thread类的子类
2. 重写Thread类的run() -->将此线程执行的操作声明在run()中
3. 创建Thread类的子类的对象
4. 通过此对象调用start()
class MulitThread extends Thread{ private static int ticket = 100; //多个线程共享一个静态变量 private static Object object = new Object(); @Override public void run(){ while (true){ synchronized(object){ //也可以使用当前类作为同步监视器 比如 MulitThread.class // try { // Thread.sleep(100); // } catch (InterruptedException e) { // e.printStackTrace(); // } if (ticket>0){ System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket); ticket--; }else { break; } } } } } public class ThreadTest{ public static void main(String[] args) { MulitThread t1 = new MulitThread(); MulitThread t2 = new MulitThread(); MulitThread t3 = new MulitThread(); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } }
创建多线程方法四: 同步方法继承Thread方式
class MuliThread extends Thread{ private static int ticket = 100; //多个线程共享一个静态变量 @Override public void run(){ while (true){ sho(); } } public static synchronized void sho(){ //此时同步监视器为MuliThread.class if (ticket>0){ System.out.println(Thread.currentThread().getName()+":买票,票号为:"+ ticket); ticket--; } } } public class Tongbu1{ public static void main(String[] args) { MulitThread t1 = new MulitThread(); MulitThread t2 = new MulitThread(); MulitThread t3 = new MulitThread(); t1.setName("窗口1"); t2.setName("窗口2"); t3.setName("窗口3"); t1.start(); t2.start(); t3.start(); } }
比较创建线程的两种方式:
两者区别:
开发中,优先选择Runnable接口的方式
1. 继承Thead类方法 ticket需要加static修饰ticket,而Runnable方法直接new的唯一一个参数对象传递到多个Thread中,具有天然的共享性
2. 继承在Java类的成面具有一定局限性(没有多继承), 实现的方式没有类单继承性的局限性
两者联系:public class Thread implement Runnable
两种方式都需要重写run(),将线程要执行的逻辑重写在run()里面。
关于同步方法的总结:
1.同步方法仍然及到同步监视器,只是不需要我们显式的声明。
2.非静态的同步方法,同步监视器是:this静态的同步方法
3. 静态的同步方法,同步监视器是:当前类本身
浙公网安备 33010602011771号