[Java] 多线程

1. 线程的创建

Thread 类是java.lang 包中的类,所以该类已经默认加载

Thread 类有多个构造方法,以实现不同形式的线程创建

public Thread()  生成一个新的线程

public Thread(String name)  生成一个新的线程,名称为name

public Thread(Runnable target)  生成一个新的线程,target 为是实现Runnable 接口的实例

public Thread(ThreadGroup group, Runnable target)  生成一个新的线程,在线程组group 中

...

线程的实现:

eg:

public class test3 {
  public static void main(String[] args){
    ExampleThread thread1, thread2, thread3;
    thread1 = new ExampleThread("A");
    thread2 = new ExampleThread("B");
    thread3 = new ExampleThread("C");
    thread1.start();
    thread2.start();
    thread3.start();
  }
}
class ExampleThread extends Thread{
  ExampleThread(String s){
    setName(s);
  }
  public void run(){
    System.out.println("执行子线程"+getName());
  }
}

执行结果:

执行子线程A
执行子线程C
执行子线程B

2. Runnable 接口

eg:

public class test3 {
    public static void main(String[] args){
      Thread thread1;
      Thread thread2;
      Thread thread3;
      thread1 = new Thread(new ExampleThread("A"));
      thread2 = new Thread(new ExampleThread("B"));
      thread3 = new Thread(new ExampleThread("C"));
      thread1.start();
      thread2.start();
      thread3.start();
  }
}
class ExampleThread implements Runnable{
  String name;
  ExampleThread(String s){
    name=s;
  }
  public void run(){
    System.out.println("执行子线程"+name);
  }
}

3.线程的调度与优先级

Java 中线程的优先级有10个级别,各级别的代号为1~10,数字越大则优先级越高,程序就会先被执行

Thread 类中设置了3个常用优先级变量
public static final int MAX_PRIORITY: 最高优先级,优先级别为10

public static final int MIN_PRIORITY: 最低优先级,优先级别为1

public static final int NORM_PRIORITY: 默认优先级,优先级别为5

Thread 类中还提供了几个方法用于优先级的设定和获取:

public final void setPriority(int newPriority): 设置线程的优先级为newPriority

public final int getPriority(): 返回线程的优先级

eg;

public class test3 {
    public static void main(String[] args){
      ExampleThread thread1, thread2, thread3;
      thread1 = new ExampleThread("A");
      thread2 = new ExampleThread("B");
      thread3 = new ExampleThread("C");

      thread3.setPriority(Thread.MAX_PRIORITY);
      thread2.setPriority(5);
      thread1.setPriority(1);

      thread1.start();
      thread2.start();
      thread3.start();
  }
}
class ExampleThread extends Thread{
  ExampleThread(String s){
    setName(s);
  }
  public void run(){
    System.out.println("执行子线程"+getName());
  }
}

运行结果

执行子线程C
执行子线程B
执行子线程A

4. 线程的互斥

在多线程的设计中,为了避免多个线程访问修改同一资源而出现冲突,我们在程序中设置了“互斥锁”的概念。我们把这一共享的资源成为临界资源,通过一个信号装置通知各个线程,同一个世界只能有一个线程访问该临界资源。这一信号装置就是“互斥锁”

互斥锁控制临界资源只能一次由一个线程访问。互斥锁的关键字为 synchronized,使用方式为:

synchronized(临界资源){

  //临界资源处理

}

eg:

public class test3 {
public static void main(String[] args){
  Account accout1=new Account(100);
  ExampleThread thread1, thread2, thread3;
  thread1 = new ExampleThread(accout1);
  thread2 = new ExampleThread(accout1);
  thread3 = new ExampleThread(accout1);

  thread1.start();
  thread2.start();
  thread3.start();
  }
}

class ExampleThread extends Thread{
  Account ac;
  ExampleThread(Account ac){
  this.ac = ac;
  }
  public void run(){
    ac.get(100);
  }
}

class Account{
  double balance;
  Account(double d){
    balance = d;
  }
  public synchronized void get(double i){
    if (balance > 0){
      try{
        Thread.sleep(1000);
      }catch(Exception e){}
      balance = balance - i;
      System.out.println("取了"+i+", 还剩"+balance);
    }
    else{
      System.out.println("无法取钱,已经没有了");
    }
  }
}

运行结果:

取了100.0, 还剩0.0
无法取钱,已经没有了
无法取钱,已经没有了

 5. 线程的同步

线程同步使用 wait() 方法和 notify() 方法,这两个方法在Object 类中已经默认继承到所有类中,可以直接调用

public final void wait() throws InterrupedException:  使线程进入阻塞状态,让出互斥锁资源,使别的线程得以运行

public final void notify():  唤醒处于阻塞状态的等待序列中的线程,得到互斥锁资源

public final void notifyAll();  唤醒处于等待序列的所有线程

eg:

实现一个货架类,货架最大容量为100,可以存货和取货。另外实现两个线程类,分别执行存货操作和取货操作,使之不空时可以取货,满时不能存货

public class test3 {
  public static void main(String[] args){
    Shelf shelf = new Shelf(100);
    GetThread thread1 = new GetThread(shelf);
    PutThread thread2 = new PutThread(shelf);

    thread1.start();
    thread2.start();
  }
}

class GetThread extends Thread{
  Shelf sf;
  GetThread(Shelf sf){
    this.sf = sf;
  }
  public void run(){
    for(int i=0; i<5; i++){
      sf.get(60);
    }
  }
}

class PutThread extends Thread{
  Shelf sf;
  PutThread(Shelf sf){
    this.sf = sf;
  }
  public void run(){
    for(int i=0; i<5; i++){
      sf.put(60);
    }
  }
}

class Shelf{
  int number;
  Shelf(int i){
    number = i;
  }
  public synchronized void get(int i){
    System.out.println("想要取货"+i+"件,货架中有"+number+"件");
    if (number-i < 0){
      try{
        System.out.println("暂时不能取货,货物不够");
        wait();    //等待被唤醒
      }catch(Exception e){}
    }
    number = number - i;
    System.out.println("取了"+i+"件, 还剩"+number+"件");
    notify();    //唤醒其他互斥锁
  }
  public synchronized void put(int i){
    System.out.println("想要存货"+i+"件,货架中有"+number+"件");
    if (number+i > 100){
      try{
        System.out.println("暂时不能存货,容量有限");
        wait();    //等待被唤醒
      }catch(Exception e){}
    }
    number = number + i;
    System.out.println("存了"+i+"件, 还剩"+number+"件");
    notify();    //唤醒其他互斥锁
   }
}

 执行结果:

当number == 0 或 100 时,程序结束

原文地址:https://www.cnblogs.com/feifeidxl/p/4745597.html