多线程(Multi-Threading)

Creating threads in Java

Two things to do to create threads in java:

  (1) Create a task (object)

  //Creating a task

  public class TaskClass implements Runnable {

    public TaskClass() { ... }

  //Implement the run method in Runnable

  void run() {

   //things to do in the task }

   }

 

  //Runnable interface

  public interface Runnable {

     void run();

   }

 

   (2) Create a thread and combine the task with the thread (object)

  1 way

  //Create a task class

  public class TaskClass implements Runnable {

     public TaskClass(...) { ... }

  //Implement the run method in Runnable

    void run() {

       //things to do in the task

    }

  }

 

  public class ThreadDemo{

    public void someMethod(){

    //Create an instance of TaskClass

    TaskClass task=new TaskClass(...);

    //Create a thread

    Thread thread=new Thread(task);

     //Start a thread

    thread.start();

    }

   }

  2 way

  //Custom thread class

  public class CustomThread extends Thread {

    public CustomThread( ) { ... }

    //Override the run method in Runnable

    void run() {

     //things to do in the task

    }

   }

 

  public class ThreadDemo{

    public void someMethod(){

    //Create a thread

     CustomThread thread1=new CustomThread( );

     //Start a thread

    thread1.start();

     //Create another thread

    CustomThread thread2=new CustomThread( );

    //Start a thread

    thread2.start();

     }

     }

main Thread

  When a program starts, the main Thread automatically starts

  The default name of the Thread: main with priority 5

 

  public static void main(String[] args){

    System.out.println("Current thread: " + Thread.currentThread());

    Thread.currentThread().setName("MyThread");

    System.out.println("After name change: " + Thread.currentThread());

  }

 

Example: create threads

  public class ThreadDemo1 {

    public static void main(String[] args) {

    String hw= “do home work”;

     String tv= “watch TV”;

    DoSomething doHW= new DoSomething( hw );

    DoSomething watchTV = new DoSomething( tv );

     }

  }

 

  

  public class DoSomething {

    private String doWhat;

    public DoSomething(String aThing) {

    this.doWhat = aThing;

    doIt();

  }

     public void doIt(){

     for (int i=0;i<5;i++)

    System.out.println(doWhat+": "+i);

   }

   }

并没有使用多线程

Create threads (solution 1)

  public class ThreadDemo1 {

    public static void main(String[] args) {

      DoSomething doHW= new DoSomething("do home work");

      DoSomething watchTV = new DoSomething(“watch TV");

      Thread hwThread= new Thread(doHW);

      Thread tvThread = new Thread(watchTV);

      hwThread.start();

      tvThread.start();

      }

    }

 

  public class DoSomething implements Runnable {

   private String doWhat;

  public DoSomething(String aThing) {

   this.doWhat = aThing;

  } public void run(){

  for (int i=0;i<5;i++)

  System.out.println(doWhat+": "+i);

   }

   }

Create threads solution 2

  public class ThreadDemo2 extends Thread {

    String doThing;

    ThreadDemo2(String doWhat){

    this.doThing=doWhat;

    }

  public static void main(String[] args) {

    String hw= "do home work";

    String tv= "watch TV";

    ThreadDemo2 thread1=new ThreadDemo2(hw);

    ThreadDemo2 thread2=new ThreadDemo2(tv);

    thread1.start();

    thread2.start();

    }

  public void run() {

    for(int i=0;i<5;i++)

      System.out.println(doThing+": "+i);

     }

  }

 

 

Control  a  Thread  

  public static void yield():

    Causes the currently executing thread object to temporarily pause

    Allow other threads to execute(执行)

    aThread.yield();

    t1.yield();

    t2.sleep(1000);

 

  static void sleep(long millis): 

    Causes the currently executing thread to sleep (block) for the specified number of milliseconds

    If the thread is blocked by sleep or wait, an InterruptedException is thrown

 

    try {

      aThread.sleep(1000);

      //sleep for 1 second

      } catch (InterruptedException ex) {

      //do sth…

      }

 

  interrupt():

   Does not stop a thread Set "interrupted" status to true Why interrupt?

  After interrupt is set, we can take actions

  isInterrupted():

  Tests whether this thread has been interrupted.

  The interrupted status of the thread is unaffected by this method.

    if(isInterrupted()){

         Action

        }

  interrupted():

  Tests whether the current thread has been interrupted.

  The interrupted status of the thread is cleared by this method.

  Returns: true if the current thread has been interrupted; false otherwise.

 

 

  public class ThreadDemo2 extends Thread {

    String doThing;

     ThreadDemo2(String doWhat){

      this.doThing=doWhat;

    }

    public static void main(String[] args) {

    String hw= "do home work";

    String tv= "watch TV";

    ThreadDemo2 thread1=new ThreadDemo2(hw);

    ThreadDemo2 thread2=new ThreadDemo2(tv);

    thread1.start();

    thread2.start();

     }

    public void run() {

      for(int i=0;i<5;i++) {

      System.out.println(doThing+": "+i);

      this.yield();

      }

    }

  }

 

 

  public class ThreadDemo2 extends Thread {

    String doThing;

    ThreadDemo2(String doWhat){

     this.doThing=doWhat;

     }

    public static void main(String[] args) {

    String hw= "do home work";

    String tv= "watch TV";

    ThreadDemo2 thread1=new ThreadDemo2(hw);

    ThreadDemo2 thread2=new ThreadDemo2(tv);

    thread1.start();

     thread2.start();

    }

    public void run() {

    for(int i=0;i<5;i++) {

     System.out.println(doThing+": "+i);

    try {

       this.sleep(10);

      } catch (InterruptedException ex) {

      System.out.println(“sth wrong”);

       }

     }

    }

   }

Ping Pong Sleep

public class PingPongSleep extends Thread{

   private String word;

  private int delay;

  public PingSleep(String whatToSay, int delayTime){

    word = whatToSay;

    delay = delayTime;

     }

  public void run(){

    for( int i=0; i<5; i++){

      System.out.print(word + " ");

        try{

           Thread.sleep(delay);

          } catch (InterruptedException e){

            System.err.println(e);

        }

       }

    }

     public static void main(String[ ] args){

    Thread ping = new PingPongSleep("ping", 500);

     Thread pong = new PingPongSleep("PONG", 1000);

    ping.start();

    pong.start();

    }

   }

Ping Pong Interruption

  public void run(){  

    for(int i=1;i<=2;i++)

    System.out.println( i+": "+word+" isInterrupted? "+ isInterrupted() );

     }

    public static void main(String[ ] args){

      Thread ping = new PingPongInterrup("ping");

      Thread pong = new PingPongInterrup("PONG");

      ping.start();

      pong.start();

      pong.interrupt();

    }

  }

    

  多线程不能控制顺序,所以前面1,2的顺序无关紧要;且PONG.interrupted是TRUE;

 

  public void run(){

    for(int i=1;i<=2;i++)

       System.out.println( i+": "+word+" interrupted? "+ interrupted() ) ;

    }

   public static void main(String[] args){

    Thread ping = new PingPongInterrup("ping");

    Thread pong = new PingPongInterrup("PONG");

    ping.start();

    pong.start();

    pong.interrupt(); 

    }

  }

 

           

  第二个PONG为false

 

join(long millis)

  Waits at most millis milliseconds for this thread to finish

  A timeout of 0 means to wait forever until the thread die

  InterruptedException is thrown

  You can only “join” a thread before it is selected by the processer

 

  try{

    aThread.start();

    aThread.join();

    }catch(InterruptedException e){

      ...

    }

 

 

  public class PingPongJoin extends Thread{

    private String word;

    private int delay;

    public PingPongJoin(String whatToSay, int delayTime){

      word = whatToSay;

      delay = delayTime;

     }

    public void run(){

       for (int i = 0; i < 5; i++){

         System.out.print(word + " ");

      try {

        Thread.sleep(delay);

       } catch (InterruptedException e){

           }

         }

      }

      public static void main(String[] args){

        Thread ping = new PingPongJoin("ping", 500);

        Thread pong = new PingPongJoin("PONG", 500);

        ping.start();  // ping started

        try {

         ping.join(); //确保输出结果会是5个ping一直在前面

           } catch (InterruptedException e){

          }

          pong.start();

         }

       }

 

Output: ping ping ping ping ping PONG PONG PONG PONG PONG 

 

Synchronization

  Two or more threads share the same resource Synchronized method:

  To make a method synchronized: add the synchronized keyword to its declaration

  When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object

 

  class CallMe{

    void call(String msg){

    System.out.print( "[" + msg) ;

    try{

      Thread.sleep(1000);

      } catch(InterruptedException e){

    System.out.println("Interrupted");

    }

    System.out.println("]");

    }

    }

 

  public class PingPongSyn extends Thread{

    private String w;

    static Callme target;

    public PingPongSyn(String whatToSay){

      w = whatToSay;

    }

    public void run(){

      target.call(w);

    }

    public static void main(String[] args){

      target = new CallMe();

      Thread ping = new PingPongSyn("ping");

      Thread pong = new PingPongSyn("PONG");

      ping.start();

      pong.start();

      }

    }

  suppose:[ping] [PONG]

Actual output:[ping[PONG]

    ping went to sleep at this point PONG got a chance to print.

 

 

  class CallMe{

    synchronized void call(String msg){

    System.out.print("[" + msg); try { Thread.sleep(1000);

     } catch(InterruptedException e){

    System.out.println("Interrupted");

    }

    System.out.println("]");

       }

    }

  The method (common resource) will block other threads when it is called by a thread

 

  public static void main(String[] args){

    target = new Callme();

    Thread ping = new PingPongSynJoin("ping");

    Thread pong = new PingPongJoin("PONG");

    ping.start();

    try{

      ping.join(); //the main thread waits until ping finishes

      } catch(InterruptedException e){

      }

      pong.start();

      }

      }

 

Difference between join() and synchronized

          

 

多线程的同步机制对资源加锁,使得只有一个线程可以操作,同步用于解决多线程同时访问某一个资源出现的问题。

join用于主线程等待子线程运行完毕它的run方法,再继续执行下面的代码。

            

 

Lock Objects

 

  ReentrantLock myLock=new ReentrantLock();

  myLock.lock();

  try {

    critical section //临界区

  } finally {

  myLock.unlock();

  }

 

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

  public class CallMe2 {

    private Lock messageLock=new ReentrantLock();   //Locked for one thread only

 

    public void call(String msg){

      messageLock.lock();

    try{

      System.out.print("[" + msg);

      Thread.sleep(1000);

      System.out.println("]");

    } catch(InterruptedException e){

      System.out.println("Interrupted");

      } finally{

      messageLock.unlock();

      }

    }

    }

 

Condition Objects

In the previous example,

  if we only want to print out “pxxx” only. What’s wrong with this solution:

 

  if((w.toUpperCase()).charAt(0)=='P'){

 

  //do something

  target.call(w);

   }

 

We can also specify some conditions for entering a critical section.

  private Condition lockCondition;

  lockCondition=lock.newCondition();// Create a condition, and attach it with a lock

   while(//condition not satisfied) //Block the thread if the condition is not satisfied. Meanwhile another thread can access the critical section

  lockCondition.await();

  …

  lockCondition.signalAll();  // Give the blocked threads another chance

 

Inter-thread Communication

  Polling problem(轮询问题):

    A loop that is used to check some condition repeatedly.

    Once the condition is true, appropriate action is taken

    This wastes CPU time

    

 

  To avoid polling, Java includes an elegant inter-process communication mechanism via the wait( ), notify( ), and notifyAll( ) methods.

  All three methods can be called only from within a synchronized method The rules:

  wait( ) tells the calling thread to give up the monitor and go to sleep until some other thread calls notify( )

  notify( ) wakes up the first thread that called wait( ) on the same object.

  notifyAll( ) wakes up all the threads that called wait( ) on the same object

 

 

 

class Car {

  int n;

  boolean carAvailable = false; // A flag that indicates car availability

  synchronized int get(){

     if(!carAvailable) { //  Check car availability

    try {

      wait(); //  Stop getting if car is not available

     } catch(InterruptedException e) {

      }

      } System.out.println("Got Car: " + n); // Get one if car is available

       carAvailable=false; // Change flag

      notify(); // Wakeup other threads

      return n;

      }

      synchronized void make(int n){

        if(carAvailable) {  // Check car availability

          try {

            wait();  //Stop making if car is already available

            } catch(InterruptedException e) {

            }

          }

          this.n = n; // Make one if car is available

      System.out.println("Made Car: " + n);

      carAvailable=true;  // Change flag

      notify();  // Wakeup other threads

      }

     }

posted @ 2017-12-16 23:12  CaiCongyu  阅读(256)  评论(0编辑  收藏  举报