Java多线程应用总结
2017-04-10 11:23
225 查看
一、基本方法
进程和线程一样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是在进程的基础上进行的进一步划分。所谓多线程,是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的单元称为线程,这些线程可以同时存在、同时运行。
Tread类中的主要方法:
二、多线程的实现方式及其异同
方式一:
方式二:
方式三:
在方式二的基础上略微改动一下。
方式一与方式二本质上没有什么差别,但是方式三却实现了真正的资源共享,其关键在于Thread类的不同构造方式,new Thread(); 与 new Tread(Runnable target); 这两种方式最终是要调用start()方法,而start()方法是在调用run()方法。因此,关键取决于所调用的run()方法。只有采用new Tread(Runnable target); 这种方式才有可能让传入的参数引用指向同一个run()方法的地址引用,这种机制本质上由于Runnable接口没有定义start()方法,而Thread()构造函数(也可以包含参数)或者说Thread类的内在能力仍然是开辟新的线程任务(引用),一视同仁,至于传入的是什么它不管,只要合法就行,只要最终可以正确的引用到run()方法就Ok了。
三 关于join()
我个人的理解是让当前的线程任务保持join,也就是在一起,不可分割,一次执行完。有点类似于synchronized()的功能,但是synchronized()的参数不能为static object。
上面这段代码中,t线程执行完后,才轮到Main 线程执行,且for循环一次执行完,中间不会穿插着t线程的任务。正常情况下,如果不采用join()方法的话,那么JVM会让t线程与main线程交替随机执行(并行执行)。
四、等待与唤醒
在生产者与消费者模式中会用到同步机制与等待唤醒机制,前者主要针对于局部,而后者更多的是关注整体的布局与策略。二者的配合可以让生产者与消费者模式稳健的运作。
super.notify()的含义是调用Object类的静态方法notify方法,它会唤醒第一个等待的线程执行,而notifyAll()会唤醒所有的等待线程。wait()方法会让当前执行的线程进入到等待状态,也可以理解为休眠状态。
进程和线程一样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是在进程的基础上进行的进一步划分。所谓多线程,是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的单元称为线程,这些线程可以同时存在、同时运行。
Tread类中的主要方法:
序 号 | 方法名称 | 类 型 | 描 述 |
1 | public Thread(Runnable target) | 构造 | 接收Runnable接口子类对象,实例化Thread对象 |
2 | public Thread(Runnable target, String name) | 构造 | 接收Runnable接口子类对象,实例化Thread对象,并设置线程名称 |
3 | public Thread(String name) | 构造 | 接收Runnable接口子类对象,并设置线程名称 |
4 | public static Thread currentThread() | 普通 | 返回目前正在执行的线程 |
5 | public final String getName() | 普通 | 返回线程的名称 |
6 | public final int getPriority() | 普通 | 返回线程的优先级 |
7 | public boolean isInterrupted() | 普通 | 判断目前线程是否被中断,如果是返回true,否则返回false |
8 | public final boolean isAlive() | 普通 | 判断线程是否在活动,如果是返回true,否则返回false |
9 | public final void join() throws Interrupted Exception | 普通 | 等待线程死亡 |
10 | public final synchronized void join(long millis) throws Interrupted Exception | 普通 | 等待millis毫秒后,线程死亡 |
11 | public void run() | 普通 | 执行线程 |
12 | public final void setName(String name) | 普通 | 设定线程名称 |
13 | public final void setPriority(int newPriority ) | 普通 | 设定线程的优先级 |
14 | public static void sleep(long millis) throws InterruptedException | 普通 | 使目前正在执行的线程休眠millis毫秒 |
15 | public void start() | 普通 | 开始执行线程 |
16 | public String toString() | 普通 | 返回代表线程的字符串 |
17 | public static void yield() | 普通 | 将目前正在执行的线程暂停,允许其他的线程执行 |
18 | public final void setDaemon(boolean on) | 普通 | 将一个线程设置成后台运行 |
方式一:
package test.thread.share.first; class MyThread extends Thread { private int ticket = 5; public void run(){ for(int i = 0; i<10; i++) if(ticket > 0){ System.out.println("买票: ticket =" + ticket--); } } } public class ThreadShare { public static void main(String[] args) { MyThread mt1 = new MyThread(); MyThread mt2 = new MyThread(); MyThread mt3 = new MyThread(); mt1.start(); mt2.start(); mt3.start(); } }
方式二:
package test.thread.share.second; class MyThread implements Runnable{ private int ticket = 5; public void run(){ for(int i=0; i<10; i++){ if(ticket > 0){ System.out.println("买票 ticket = " + ticket--); } } } } public class ThreadShare { public static void main(String[] args) { new Thread(new MyThread()).start(); new Thread(new MyThread()).start(); new Thread(new MyThread()).start(); } }
方式三:
在方式二的基础上略微改动一下。
package test.thread.share.second; class MyThread implements Runnable{ private int ticket = 5; public void run(){ for(int i=0; i<10; i++){ if(ticket > 0){ System.out.println("买票 ticket = " + ticket--); } } } } public class ThreadShare { public static void main(String[] args) { // new Thread(new MyThread()).start(); // new Thread(new MyThread()).start(); // new Thread(new MyThread()).start(); MyThread my = new MyThread(); new Thread(my).start(); new Thread(my).start(); new Thread(my).start(); } }
方式一与方式二本质上没有什么差别,但是方式三却实现了真正的资源共享,其关键在于Thread类的不同构造方式,new Thread(); 与 new Tread(Runnable target); 这两种方式最终是要调用start()方法,而start()方法是在调用run()方法。因此,关键取决于所调用的run()方法。只有采用new Tread(Runnable target); 这种方式才有可能让传入的参数引用指向同一个run()方法的地址引用,这种机制本质上由于Runnable接口没有定义start()方法,而Thread()构造函数(也可以包含参数)或者说Thread类的内在能力仍然是开辟新的线程任务(引用),一视同仁,至于传入的是什么它不管,只要合法就行,只要最终可以正确的引用到run()方法就Ok了。
三 关于join()
我个人的理解是让当前的线程任务保持join,也就是在一起,不可分割,一次执行完。有点类似于synchronized()的功能,但是synchronized()的参数不能为static object。
public static void main(String[] args) { MyThread mt = new MyThread(); Thread t = new Thread(mt, "线程"); t.start(); for(int i=0; i<50; i++){ if(i>10){ try{ t.join(); } catch(Exception e){ } System.out.println("Main 线程运行 ---> " + i); } } }
上面这段代码中,t线程执行完后,才轮到Main 线程执行,且for循环一次执行完,中间不会穿插着t线程的任务。正常情况下,如果不采用join()方法的话,那么JVM会让t线程与main线程交替随机执行(并行执行)。
四、等待与唤醒
在生产者与消费者模式中会用到同步机制与等待唤醒机制,前者主要针对于局部,而后者更多的是关注整体的布局与策略。二者的配合可以让生产者与消费者模式稳健的运作。
class Info { private String name = "张三"; private String content = "管理员"; private boolean flag = false; public synchronized void set(String name, String content){ if(!flag){ try{ super.wait(); } catch(InterruptedException ex){ ex.printStackTrace(); } } this.setName(name); try{ Thread.sleep(300); } catch(InterruptedException ex){ ex.printStackTrace(); } this.setContent(content); flag = false; super.notify(); } public synchronized void get(){ if(flag){ try{ super.wait(); } catch(InterruptedException ex){ ex.printStackTrace(); } } try{ Thread.sleep(300); } catch(InterruptedException ex){ ex.printStackTrace(); } System.out.println(this.getName() + "-->" + this.getContent()); flag = true; super.notify(); } public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getContent(){ return content; } public void setContent(String content){ this.content = content; } }
super.notify()的含义是调用Object类的静态方法notify方法,它会唤醒第一个等待的线程执行,而notifyAll()会唤醒所有的等待线程。wait()方法会让当前执行的线程进入到等待状态,也可以理解为休眠状态。
相关文章推荐
- Java【多线程知识总结(9)】Timer类与TimerTask类的应用---模拟定时炸弹
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- JAVA多线程实现和应用总结
- 给你们说说JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结
- JAVA多线程实现和应用总结:如何使用有返回值的多线程
- Java【多线程知识总结(9)】Timer类与TimerTask类的应用---模拟定时炸弹
- Java【多线程知识总结(7)】多线程同步问题-关于synchronized代码块和synchronized方法的应用
- 高级应用JAVA多线程详解(二)
- Java 多线程总结
- java语言多线程程序总结
- java基础5--多线程--要点总结
- Java多线程编程总结--新特征-条件变量
- Java数据结构应用——无序列表学习总结(二)