Java并行程序基础

来源:互联网 发布:淘宝改一口价的技巧 编辑:程序博客网 时间:2024/05/19 12:13


线程的生命周期:


线程的基本操作:

1, 新建线程:使用new关键字创建一个线程对象,将它start()起来即可。start()方法会新建一个线程并让这个线程执行run()方法。如果用run()方法来开启线程,只是做为一个普通的方法调用。


2,终止线程:stop()方法会在结束线程时,会直接终止线程,并立即释放这个线程持有的锁。太过于暴力,强行把执行到一半的线程终止,可能会引起一些数据不一致的问题。代码来源于葛一鸣编著的Java高并发程序设计(侵权必删)代码的执行结果表示使用stop()方法会导致数据不一致的结果,所以不要随便使用stop()方法来停止一个线程。

import java.lang.*;import java.lang.Exception.*;public class StopThreadUnsafe{public static User u = new User();public static class User{private int id;private String name;public User(){id=0;name="0";}public void setId(int id){this.id = id;}public int getId(){return this.id;}public void setName(String name){this.name = name;}public String getName(){return name;}public String toString(){return "User [id="+id+",name="+name+"]";}}public static class ChangeObjectThread extends Thread{public void run(){while(true){synchronized(u){int v = (int)(System.currentTimeMillis()/10000);u.setId(v);try{Thread.sleep(100);}catch(InterruptedException e){e.printStackTrace();}u.setName(Integer.toString(v));}Thread.yield();}}}public static class ReadObjectThread extends Thread{public void run(){while(true){synchronized(u){if(u.getId() != Integer.parseInt(u.getName().trim()))System.out.println(u.toString());}Thread.yield();}}}public static void main(String[] args) throws InterruptedException{new ReadObjectThread().start();while(true){Thread t = new ChangeObjectThread();t.start();Thread.sleep(150);t.stop();}}}

3,线程中断:线程中断并不会使线程立即退出,而是给线程发送一个通知,至于目标线程接到通知后如何处理,完全由目标线程自行决定。
 
与中断线程有关的三个方法:
public void Thread.interrupt()  //中断线程public void  Thread.isInterrupted() //判断是否被中断public void Thread.interrupted() //判断是否被中断,并清除当前中断状态。
如果希望线程在中断后退出,就必须为它增加相应的中断处理代码。

4,等待(wait)和通知(notify)
方法签名如下:
public final void wait() throws InterruptedExceptionpublic final native void notify()
这两个方法是在Object类中;如果线程A调用了obj.wait()方法,那么线程A就会停止执行,转化为等待状态,直到有其他线程调用了obj.notify()为止才结速等待。
Object.wait()方法必须包含在对应的synchronzied语句中,无论是wait()还是notify()都需要首先获得目标对象的一个监视器,而在方法执行后都会释放这个监视器。
wait和notify的工作流程细节如下:

Object.wait()和Thread.sleep()的区别:都可以让线程等待若干时间
wait()方法可以被唤醒,wait()方法会释放目标对象的锁,而sleep()方法不会释放任何资源。


5,挂起(suspend)和继续执行(resume)线程:
suspend()在导致线程暂停的同时,并不会去释放任何锁资源。任何其他线程想要访问被它暂用的锁的时,都会被牵连,无法正常继续运行。对于被挂起的线程,从它的线程状态看,是Runnable,如果resume操作意外地发生在suspend()前,那么被挂起的线程就很难有机会被执行了。

6,等待线程结束(join)和谦让(yield)
join()方法签名:
public final void join() throws InterruptedExceptionpublic final synchronzied void join(long millis) throws InterruptedException
第一个join()方法表示无限等待,它会一直阻塞当前线程,直到目标线程执行完毕。第二个会给出一个最大等待时间。
如果超过给定时间目标线程还在执行,当前线程也会因为“等不及”,而继续往下执行。
yield()方法签名:
public static native void yield();
使当前线程让出CPU,在让出CPU后,还会进行CPU资源的争夺。