【JAVA】多线程编程实现实例(全面实现) |
您所在的位置:网站首页 › java线程太多 › 【JAVA】多线程编程实现实例(全面实现) |
首先,我们我们要进行多线程编程,最少线程怎么创建时最基本的知识。 创建线程由四种方式 1.继承Thread类创建线程(重写run方法,用start()开启线程) 2.实现Runable接口创建线程(重写run方法,也是start来开启线程) 3.使用Callable和Future创建线程(用Lambda表达式创建Callable对象,用Future来包装该对象,可以有返回值) 4.使用线程池(Executore框架) 我们创建一个场景,有三个站台再卖20张票,再一个站台卖某张票的时候,其他站台不能同时卖这张票。 线程创建方式知道了,那么多线程编程还有一个很重要的就是怎么同步 1.synchronized关键字 2.Atomic实现原子性 3.lock锁 1、继承Thread类创建线程 synchronized关键字 import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; public class TestThread2 { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); Station1 st1 = new Station1("station 1",countDownLatch); Station1 st2 = new Station1("station 2",countDownLatch); Station1 st3 = new Station1("station 3",countDownLatch); long time = System.currentTimeMillis(); st1.start(); st2.start(); st3.start(); countDownLatch.await(); System.out.println((System.currentTimeMillis() - time)); } } class Station1 extends Thread { static CountDownLatch countDownLatch; Object lock = "lock"; static int tick = 20;//保持多个站台线程间票量一直要用static public Station1(String name, CountDownLatch countDownLatch){ super(name);//给线程命名 this.countDownLatch = countDownLatch; } @Override public void run(){ while(tick > 0){ synchronized (lock){ if(tick > 0){ System.out.println(getName() + " 卖出了第" + tick + "张票" ); tick--; //System.out.println("剩下 " + tick + " 张票" ); }else { System.out.println("票卖完了"); } try { sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } } countDownLatch.countDown(); } }输出结果,可以看到卖20张票因为synchronized锁的缘故,时间非常慢,要用20多秒,synchronized的效率问题已经很直观了。 结果 可以看到,Atomic和lock的时间差不多,因为底层实现都是CAS,所以比synchronized要快很多,AtomicInteger用起来比较方便,所以后面的例子值用AtomicInteger来实现。 2、实现Runable接口创建线程可以看到,第一个不同是实现了Runnable接口的Station类并不是一个Thread对象,所以在start的时候需要new一个Thread对象然后执行,这一步,没有Thread方便。 第二个是给线程命名需要自己手动写,所以也麻烦了不少。 Runnable接口的好处就是实现了Runnable接口还可以实现别的接口,但是继承了Thread类就只能继承这一个类了,所以可以根据情况进行选择。 import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import static java.lang.Thread.sleep; public class TestThread { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); Station st1 = new Station("station 1",countDownLatch); Station st2 = new Station("station 2",countDownLatch); Station st3 = new Station("station 3",countDownLatch); long time = System.currentTimeMillis(); new Thread(st1).start(); new Thread(st2).start(); new Thread(st3).start(); countDownLatch.await(); System.out.println((System.currentTimeMillis() - time)); } } class Station implements Runnable { static CountDownLatch countDownLatch; static AtomicInteger tick = new AtomicInteger(20);//保持多个站台线程间票量一直要用static String name; public Station(String name, CountDownLatch countDownLatch){ this.name = name;//给线程命名 this.countDownLatch = countDownLatch; } public String getName() { return name; } @Override public void run(){ while(tick.get() > 0){ if(tick.get() > 0){ int i = tick.getAndDecrement(); System.out.println(getName() + " 卖出了第" + i + "张票" ); //System.out.println("剩下 " + tick + " 张票" ); }else { System.out.println("票卖完了"); } try { sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } countDownLatch.countDown(); } }在JDK8出来后,使用Callable和Future创建线程可以用Lambda表达式来创建线程 import java.awt.*; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.FutureTask; import java.util.concurrent.atomic.AtomicInteger; import static java.lang.Thread.sleep; public class TestThread { public static void main(String[] args) throws InterruptedException { CountDownLatch countDownLatch = new CountDownLatch(3); long time = System.currentTimeMillis(); AtomicInteger tick = new AtomicInteger(20); for(int i = 0; i < 3 ;++ i){ FutureTask station = new FutureTask((Callable)()->{ while(tick.get() > 0){ if(tick.get() > 0){ int j = tick.getAndDecrement(); System.out.println(Thread.currentThread().getName() + " 卖出了第" + j + "张票" ); //System.out.println("剩下 " + tick + " 张票" ); }else { System.out.println("票卖完了"); } try { sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } } countDownLatch.countDown(); return tick.get(); }); new Thread(station, "station" + i).start(); } countDownLatch.await(); System.out.println((System.currentTimeMillis() - time)); } }结果 结果 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |