Java 多线程
来源:互联网 发布:医疗服务行业数据 编辑:程序博客网 时间:2024/05/17 06:29
1.java多线程的两种形式
1.1Thread子类形式
public class MyThread extends Thread{ @Override public void run() { for (int i=0;i<500;i++){ System.out.println( getName()+":"+i); } }}public class ThreadDemo { public static void main(String[] args) throws InterruptedException { MyThread myThread1=new MyThread(); MyThread myThread2=new MyThread(); myThread1.start(); myThread2.start(); System.out.println("over..."); }}
1.2 Runable形式
class MyRunable implements Runnable{ @Override public void run() { for (int i=0;i<200;i++){ //注意这里调用线程名称的方式 System.out.println(Thread.currentThread().getName() + ":" + i); } }}public class ThreadRunableDemo { public static void main(String[] args) { Runnable r1= new MyRunable(); new Thread(r1,"clow").start(); new Thread(r1,"jop").start(); //当然也可以使用内部类 Runnable r2=new MyRunable(){ @Override public void run() { for (int i=10;i<120;i++){ //注意这里调用线程名称的方式 System.out.println(Thread.currentThread().getName() + ":" + (char)i); } } }; new Thread(r2,"alex").start(); }}
1.3 内部类线程
内部类可以类比于C#的委托-拉姆达表达式,同层次的变量在run方法是可以直接使用的,这和拉姆达表达式一样
public class InnerThreadDemo { public static void main(String[] args) { //继承Thread类实现多线程 new Thread(){ @Override public void run() { for (int i=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()+": "+i); } } }.start(); //使用Runnable实现 new Thread(new Runnable() { @Override public void run() { for (int i=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()+": "+i); } } }).start(); }}
1.4二者的比较
Runable解决了java单继承类的局限问题,而且它减少了代码的耦合性,所有推荐使用第二种方法!
2.电影票问题
假设一家电影院有3个电影售票窗口,同时出售《复仇者联盟4》的电影票共100张,如何模拟?
2.1Thread子类实现形式
class TicketTread extends Thread { private static int ticketnum = 100; @Override public void run() { while(ticketnum>0){ System.out.println("windows_"+ getName()+":The current ticket number is "+ticketnum--); } }}class TicketTreadDemo { public static void main(String[] args) { TicketTread t1=new TicketTread(); TicketTread t2=new TicketTread(); TicketTread t3=new TicketTread(); t1.start(); t2.start(); t3.start(); }}
2.2Runable 实现形式
class Ticket implements Runnable { private int ticketnum = 100; @Override public void run() { while(ticketnum>0){ System.out.println("windows_"+Thread.currentThread().getName()+":The current ticket number is "+ticketnum--); } }}class TicketRunableDemo { public static void main(String[] args) { Ticket t =new Ticket(); new Thread(t,"1").start(); new Thread(t,"2").start(); new Thread(t,"3").start(); }}
从上面的2例子可以看出对于相同的代码,使用runable的方法更灵活方便,但是他们都还存在一个问题,比如某一张票会被卖了2次,这就是所谓的临界区问题了。
2.3Runable 最终实现形式
如上的售票必须使用同步才行,java的synchronized方法和C#的lock方法类似。
class Ticket implements Runnable { private int ticketnum = 100; private Object obj = new Object(); @Override public void run() { synchronized (obj) { while (ticketnum > 0) { System.out.println("windows_" + Thread.currentThread().getName() + ":The current ticket number is " + ticketnum--); } } }}
当然也可以使用同步方法放在run里面,但类是实例类的时候,它锁的对象的this; 当方法是静态的时候,它锁的是类的Xxx.class的字节码对象
public synchronized void sellTicket(){ while (ticketnum > 0) { System.out.println("windows_" + Thread.currentThread().getName() + ":The current ticket number is " + ticketnum--); } }
继jdk5推出了类似PV操作的上锁和解锁操作
class Ticket implements Runnable { private int ticketnum = 100; Lock lock=new ReentrantLock(); //实例化一个锁 @Override public void run() { try { lock.lock(); //上锁 while (ticketnum > 0) { System.out.println("windows_" + Thread.currentThread().getName() + ":The current ticket number is " + ticketnum--); } }finally { lock.unlock(); //解锁 } }}
2.线程池
1.Runable类型
lass ThreadPool implements Runnable { @Override public void run() { for (int i=0;i<200;i++){ System.out.println(Thread.currentThread().getName()+" "+i); } }} class ThreadPoolDemo{ public static void main(String[] args) { ExecutorService pool= Executors.newFixedThreadPool(2);//创建包含2个线程的线程池 pool.submit(new ThreadPool()); pool.submit(new ThreadPool()); //此时线程执行完会被回收,使用下面方法结束线程池 pool.shutdown(); } }
2.Callable类型
其和C#中的BackgroundWork类似,都是执行一段代码并返回结果。而在java中其自动阻塞主线程效果
class MyCallable implements Callable<Integer> { private int number; public MyCallable(int number){ this.number=number; } @Override public Integer call() throws Exception { int sum=0; for (int i=1;i<=number;i++){ sum+=i; } Thread.sleep(7000); return sum; }}class MyCallableDemo{ public static void main(String[] args) throws Exception { ExecutorService pool= Executors.newFixedThreadPool(2); Future<Integer> f1=pool.submit(new MyCallable(100)); Future<Integer> f2=pool.submit(new MyCallable(200)); int i1=f1.get();//get会阻塞主线程直到拿到结果 int i2=f2.get(); System.out.println("打印输出"); System.out.println(i1);//5050 System.out.println(i2);//20100 }}
3.定时器
如下代码为当前显示时间
//schedule(TimerTask task, long delay, long period)//period为时间间隔class MyTask extends TimerTask{ @Override public void run() { System.out.println(new Date().toString()); }}class TimerDemo { public static void main(String[] args) { Timer t=new Timer(); TimerTask task=new MyTask(); t.schedule(task, 0, 1000); //第一次无延迟,每秒执行一次 //t.cancel(); //干掉时间任务的子线程,才能推出主线程 System.out.println("over.."); }}
0 0
- 【Java多线程】多线程死锁
- Java 多线程
- java 多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA多线程
- java多线程
- JAVA 多线程
- Java多线程
- java多线程
- JAVA 多线程
- Java 多线程
- Java 多线程
- java多线程
- Java 多线程
- Java多线程
- java 多线程
- bzoj1532【POI2005】Kos-Dicing
- 【学习】Javascript设计模式——Module模式
- 获取局域网MAC思路
- 反思
- android5.0自带兼容控件__SwipeRefreshLayout
- Java 多线程
- 什么是显热?什么是潜热?
- Xcode9中开发phoneGap应用ajax异常的解决办法
- Keil调试局部变量显示"not in scope"的问题解决
- 我的iOS学习历程 - UICollection详解
- Leetcode 第6题ZigZag Conversion
- 字节对齐
- PHP开发环境配置
- java并发--队列同步器原理一