您的位置:首页 > 编程语言 > Java开发

Java多线程应用总结

2017-04-10 11:23 225 查看
一、基本方法

进程和线程一样,都是实现并发的一个基本单位。线程是比进程更小的执行单位,线程是在进程的基础上进行的进一步划分。所谓多线程,是指一个进程在执行过程中可以产生多个更小的程序单元,这些更小的单元称为线程,这些线程可以同时存在、同时运行。

Tread类中的主要方法:

序 号方法名称类 型描 述
1public Thread(Runnable target)构造接收Runnable接口子类对象,实例化Thread对象
2public Thread(Runnable target, String name)构造接收Runnable接口子类对象,实例化Thread对象,并设置线程名称
3public Thread(String name)构造接收Runnable接口子类对象,并设置线程名称
4public static Thread currentThread()普通返回目前正在执行的线程
5public final String getName()普通返回线程的名称
6public final int getPriority()普通返回线程的优先级
7public boolean isInterrupted()普通判断目前线程是否被中断,如果是返回true,否则返回false
8public final boolean isAlive()普通判断线程是否在活动,如果是返回true,否则返回false
9public final void join() throws Interrupted Exception普通等待线程死亡
10public final synchronized void join(long millis) throws Interrupted Exception普通等待millis毫秒后,线程死亡
11public void run()普通执行线程
12 public final void setName(String name)普通设定线程名称
13public final void setPriority(int newPriority )普通设定线程的优先级
14public static void sleep(long millis) throws InterruptedException普通使目前正在执行的线程休眠millis毫秒
15public void start()普通开始执行线程
16public String toString()普通返回代表线程的字符串
17public static void yield()普通将目前正在执行的线程暂停,允许其他的线程执行
18public 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()方法会让当前执行的线程进入到等待状态,也可以理解为休眠状态。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: