java线程等待、设置优先级、同步、挂起、恢复(Join、setPriority、synchronized、wait、notify……)

来源:互联网 发布:大圣传 知乎 编辑:程序博客网 时间:2024/06/06 10:04

一、线程等待Join示例

//代码来源:JBuilder9程序设计--java程序员成功之路      P230

class NewThread implements Runnable{
       String name;
       Thread t;
       NewThread(String threadname){
           name=threadname;
           t=new Thread(this,name);
           System.out.println("New thread: "+t);
           t.start();
       }
public void run(){
         try {
                for (int i = 5; i > 0; i--) {
                    System.out.println(name+": "+i);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException ex) {
                System.out.println(name+" interrupted.");
               }
               System.out.println(name+"Exiting.");

       }
}
public class MultiThreadDemo {
         public static void main(String[] args) {
          NewThread ob1=new NewThread("One");
          NewThread ob2=new NewThread("Two");
          NewThread ob3= new NewThread("Three");
          System.out.println("Thread One is alive: "+ob1.t.isAlive());
          System.out.println("Thread Two is alive: "+ob2.t.isAlive());
          System.out.println("Thread Three is alive: "+ob3.t.isAlive());
            try {
               // Thread.sleep(5000);
               System.out.println("Waiting for threads to finish.");
               ob1.t.join();
               ob2.t.join();
               ob3.t.join();
            } catch (InterruptedException ex) {
                System.out.println("Main thread Interrupted.");
            }
         System.out.println("Thread One is alive: "+ob1.t.isAlive());
         System.out.println("Thread Two is alive: "+ob2.t.isAlive());
         System.out.println("Thread Three is alive: "+ob3.t.isAlive());
          System.out.println("Main thread exiting.");
         }
}

run() 和start() 是大家都很熟悉的两个方法。把希望并行处理的代码都放在run() 中;stat() 用于自动调用run(),这是JAVA的内在机制规定的。并且run() 的访问控制符必须是public,返回值必须是void(这种说法不准确,run() 没有返回值),run()不带参数。Join方法:是让当前线程等待调用此方法的线程结束。

二、线程优先级示例

//JBuilder9程序设计      P232 
class clicker implements Runnable{
        int click=0;
        Thread t;
        private volatile boolean running=true;
        public clicker(int p){
            t=new Thread(this);
           t.setPriority(p);
        }
        public void run(){
            while(running){
                click++;
            }
        }
        public void stop(){
            running=false;
        }
        public void start(){
            t.start();
        }
}
public class HiLoPri {
        public static void main(String[] args) {
           // HiLoPri hilopri = new HiLoPri();
          Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
           clicker hi=new clicker(Thread.NORM_PRIORITY+2);
           clicker lo=new clicker(Thread.NORM_PRIORITY-2);
           lo.start();
           hi.start();
           try {
               Thread.sleep(10000);
           } catch (InterruptedException ex) {
               System.out.println("Main thread interrupted.");
          }
          lo.stop();
          hi.stop();
          try {//等待子线程结束
          hi.t.join();
              lo.t.join();
          } catch (InterruptedException ex) {
              ex.printStackTrace();
          }
          System.out.println("Low-priority thread: "+lo.click);
          System.out.println("High-priority thread: "+hi.click);
        }
}

volatile用以确保running值在while循环中每次都验证,如果不用volatile,Java可以自由进行优化循环

三、线程同步

class Callme{
void call(String msg){
     //synchronized     void call(String msg){
           System.out.print("["+msg);
           try {
               Thread.sleep(1000);
           } catch (InterruptedException ex) {
               System.out.println("Callme Interrupted");
            
           }
           System.out.println("]");
       }
}
class Caller implements Runnable{ //引用了Callme的实例及一个String,分别存在target和msg中
       String msg;
       Callme target;
       Thread t;
       public Caller(Callme targ,String s){
           target =targ;
           msg=s;
           t=new Thread(this);
           t.start();
       }
       public void run(){
           target.call(msg);
       }
}
public class Synch {
       public static void main(String[] args) {
         //     Synch synch = new Synch();
         Callme target=new Callme();
         Caller ob1=new Caller(target,"Hello");
         Caller ob2=new Caller(target,"Synchronized");
         Caller ob3=new Caller(target,"World");
         try {
             ob1.t.join();
             ob2.t.join();
             ob3.t.join();
         } catch (InterruptedException ex) {
             System.out.println("Interrupted");
          
         }
       }
}

说明:

1.该程序中没有阻止3个线程同时调用同一对象同一方法,使用使消息串的混合输出!

输出结果:[Hello[Synchronized[World]
]
]

2.若改为synchronized     void call(String msg){,可阻止一个线程使用Call()时其他线程进入Call().
输出结果:[Synchronized]
[Hello]
[World]
3.也可使用同步语句块解决:将这个类的定义方法的调用放入一个synchronized块内即可。

synchronized(object){ 需要同步的语句}

改后如下: public void run(){
           synchronized (target) {
                 target.call(msg);
           }
        }

运行会得出同样正确的结果,每个线程运行前都等待先前的线程结束。

四、线程挂起、恢复和终止线程

Java2不建议使用Thread定义的suspend(),resume(),stop()方法,因为suspend()有时会造成死锁。

有代表性的做法是用一个标志变量来指示纯种状态。下面代码中suspendFlag是true,则wait()方法调用以挂起线程,suspendFlag由myresume()方法设为false,使用notify()方法来唤起线程。

class Mythread implements Runnable{
      String name;
      Thread t;
    boolean suspendFlag;
      Mythread(String threadname){
          name=threadname;
          t=new Thread(this,name);
          System.out.println("New thread: "+t);
          suspendFlag=false;
          t.start();
      }
    
      public void run(){
          try {
              for (int i = 15; i > 0; i--) {
                  System.out.println(name+": "+i);
                  Thread.sleep(200);
                  synchronized (this) {
                      while (suspendFlag) {
                          wait();
                      }
                  }
              }
          } catch (InterruptedException ex) {
              System.out.println(name+" interrupted.");
          }
          System.out.println(name+" exiting.");
      }
      void mysuspend(){
        suspendFlag=true;
      }
      synchronized void myresume(){
          suspendFlag=false;
          notify();
      }
}
public class SuspendResume {
      public static void main(String[] args) {
         Mythread ob1=new Mythread("One");
         Mythread ob2=new Mythread("Two");
         try {
             Thread.sleep(1000);
             ob1.mysuspend();
             System.out.println("Suspending thread One");
             Thread.sleep(1000);
             ob1.myresume();
             System.out.println("Resuming thread one");
             ob2.mysuspend();
             System.out.println("Suspending thread Two");
             Thread.sleep(1000);
             ob2.myresume();
             System.out.println("Resuming thread Two");

         } catch (InterruptedException ex) {
             System.out.println("Main thread Interrupted.");
         }
         try {
             System.out.println("Waiting for threads to finish.");
             ob1.t.join();
             ob2.t.join();
         } catch (InterruptedException ex) {
             System.out.println("Main thread Interrupted.");
         }
         System.out.println("Main thread exiting.");
      }
}
输出结果:

New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
Two: 15
One: 15
One: 14
Two: 14
Two: 13
One: 13
Two: 12
One: 12
Two: 11
One: 11
Suspending thread One
Two: 10
Two: 9
Two: 8
Two: 7
Two: 6
Resuming thread one
One: 10
Suspending thread Two
One: 9
One: 8
One: 7
One: 6
Resuming thread Two
Two: 5
Waiting for threads to finish.
One: 5
Two: 4
One: 4
Two: 3
One: 3
Two: 2
One: 2
Two: 1
One: 1
Two exiting.
One exiting.

Main thread exiting.


zz. http://blog.csdn.net/foart/article/details/5017715

0 0