1.Thread类与Runable接口实现多线程的区别
例子:
package com.ylfeiu.multThread; /** * 本程序演示3个线程对象各自做各自的,总共卖了15张票 * * @author Administrator * */ public class SaleTicket extends Thread { int ticket = 5; @Override public void run() { for (int i = 0; i < 50; i++) { if (this.ticket> 0) { System.err.println("还剩" + this.ticket-- + "张票"); } } } public static void main(String[] args) { SaleTicket my = new SaleTicket(); SaleTicket my1 = new SaleTicket(); SaleTicket my2 = new SaleTicket(); my.start(); my1.start(); my2.start(); } }
package com.ylfeiu.multThread; public class SaleTicket2 implements Runnable { int ticket = 5; @Override public void run() { for (int i = 0; i < 50; i++) { if (this.ticket > 0) { System.err.println("还剩" + this.ticket-- + "张票"); } } } public static void main(String[] args) { SaleTicket2 my = new SaleTicket2(); new Thread(my).start(); new Thread(my).start(); new Thread(my).start(); } }
package com.ylfeiu.multThread; /** * * * @author Administrator * */ public class SaleTicket3 extends Thread { int ticket = 5; @Override public void run() { for (int i = 0; i < 50; i++) { if (this.ticket> 0) { System.err.println("还剩" + this.ticket-- + "张票"); } } } public static void main(String[] args) { SaleTicket3 my = new SaleTicket3();//本身已经有了start()方法 new Thread(my).start(); new Thread(my).start(); new Thread(my).start(); } }
通过以上三个卖票程序的对比,依靠Runnable接口实现的线程体类没有start()方法,而继承了Thread类的线程体类有start()方法定义.若通过Thread继承的多线程主类再利用Thread类去实现多线程明显不合适
所以说Runnale接口要比Thread类更好地实现了数据共享,而不是唯一
2.线程同步
同步问题指的就是多个线程操作同一资源时所带来的信息安全性问题;
如何做到同步呢?让多个操作在同一时间段内只有一个线程执行
同步采用synchronized
package com.ylfeiu.multThread; public class UnSynchronized implements Runnable { int ticket = 5; @Override public void run() { for (int i = 0; i < 50; i++) { if (this.ticket > 0) { try { Thread.sleep(2000);// 产生线程安全问题,不同步 } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("还剩" + this.ticket-- + "张票"); } } } public static void main(String[] args) { UnSynchronized my = new UnSynchronized(); new Thread(my).start(); new Thread(my).start(); new Thread(my).start(); } }
package com.ylfeiu.multThread; public class SynchronizedSale implements Runnable { int ticket = 5; @Override public void run() { for (int i = 0; i < 50; i++) { sale(); } } private synchronized void sale() {//同步 if (this.ticket > 0) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.err.println("还剩" + this.ticket-- + "张票"); } } public static void main(String[] args) { SynchronizedSale my = new SynchronizedSale(); new Thread(my).start(); new Thread(my).start(); new Thread(my).start(); } }
3.死锁
两个线程都在等待彼此先完成,造成程序停滞状态
B对A说你把你的笔给我,我就给你书
A对B说你把你的书给我,我就给你笔
package com.ylfeiu.multThread; public class DeadLock implements Runnable { static A a = new A(); static B b = new B(); boolean flag; @Override public void run() { if (flag) {// a开始执行,a说了一句话后就开始等待来自b的东西(同步b) synchronized (a) { a.say(); try { Thread.sleep(1000);// 加入延迟 } catch (InterruptedException e) { e.printStackTrace(); } synchronized (b) {// 同步第二个对象 a.get(); } } } else { synchronized (b) { b.say(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (a) { b.get(); } } } } public static void main(String[] args) { DeadLock t1 = new DeadLock(); DeadLock t2 = new DeadLock(); t1.flag = true;// t2.flag = false;// 这里一个线程是true,一个是false就让它们产生了矛盾,所以两个都一直在那里等待 new Thread(t1).start(); new Thread(t2).start(); } } class A { void say() { System.err.println("A对B说你把你的书给我,我就给你笔"); } void get() { System.err.println("A得到了书"); } } class B { void say() { System.err.println("B对A说你把你的笔给我,我就给你书"); } void get() { System.err.println("B得到了笔"); } }