Java SE入门(二十二)——多线程

Java SE入门(二十二)——多线程
  iwehdio的博客园:https://www.cnblogs.com/iwehdio/

1、多线程

  • 进程:当前正在运行的程序,即一个应用程序在内存中的执行区域。

  • 线程:进程中的一个执行控制单元。一个进程可以有一个线程,也可以有多个线程。

  • 单线程:安全性高但是效率低。多线程:安全性低但是效率高。

  • CPU执行线程具有随机性。

  • 多线程的实现方式1 :Thread 类。

    1. 写一个子类,继承 Thread 类。
    2. 在子类中重写 Thread 类的 run 方法,内容是线程的操作内容。
    3. 创建线程实例。
    4. 使用 .start() 方法启动线程。
    public class MyThread extends Thread {
        @Override
        public void run(){
            System.out.println("线程");
            System.out.println(getName());
        }
    }
    
    MyThread mt = new MyThread();
    mt.setName("线程A");
    mt.start();
  • Thread 类中的方法:

    • String getName():获取线程的名字。
    • void setName(String name):改变线程名字。
    • static Thread currentThread():返回对当前正在执行的线程对象的引用。
    • static void sleep(long millis):将线程休眠一段时间。
  • 主方法是单线程的。

  • 多线程的实现方式2 :实现 Runnable 接口。

    1. 写一个子类,实现 Runnable 接口。
    2. 在子类中重写 run 方法,内容是线程的操作内容。
    3. 创建线程实例,并将其作为参数传入 Thread 对象。
    4. 使用 .start() 方法启动线程。
    public class MyThread implements Runnable {
        @Override
        public void run(){
            System.out.println("线程");
          System.out.println(Thread.currentThread().getName());
        }
    }
    
    MyThread mt = new MyThread(); // 可以只创建一个,但是所有 Thread 对象会共享成员变量
    Thread t1 = new Thread(mt);   // 将实现的接口的对象作为参数传入
    t1.setName("线程A");
    t1.start();
    Thread t2 = new Thread(mt);
    t2.setName("线程B");
    t2.start();
  • 为什么多线程需要第二种方法的接口实现:因为 Java 中单一继承的原因,继承了 Thread 类就无法继承其他类。

  • 线程的生命周期:

    1. 新建:创建线程对象。
    2. 就绪:具备了执行条件,但没有执行权利。
    3. 运行:具备了执行权利。
    4. 死亡:作为垃圾回收。
    • 等待与唤醒:void wait():使当前线程等待。void notify():唤醒等待的线程。需要使用锁对象调用,调用线程被唤醒后先进入就绪状态。

2、同步

  • 多个线程共享同一个数据并且并发访问共享的数据,可能会出错。

  • synchronized关键字:表示同步,可以修饰代码块和方法。被修饰的代码块和方法一旦被某个线程访问,则直接锁住,其他线程无法访问。

    • 同步代码块:

      synchronized(锁对象){
          // 执行代码
      }
    • 同步方法:

      private synchronized void method(){
          // 执行代码
      }
    • 锁对象需要被所有的线程所共享,非静态同步方法的锁对象默认为 this ,静态同步方法的锁对象默认为当前类的字节码对象。

  • 同步:安全性高,效率低。

3、分票案例

public class Ticket implements Runnable{
    int tickets = 100;
    Object obj = new Object();
    
    @Override
    public void run(){
        while(true){
            method();
        }
    }
    public synchronized void method(){
        if(tickets > 0){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + ":" + tickets--);
        }
    }

}

public class Demo {
    public static void main(String[] args) {
        Ticket t = new Ticket();
        Thread td1 = new Thread(t);
        td1.setName("A");
        Thread td2 = new Thread(t);
        td2.setName("B");
        Thread td3 = new Thread(t);
        td3.setName("C");
        
        td1.start();
        td2.start();
        td3.start();
    }
}



iwehdio的博客园:https://www.cnblogs.com/iwehdio/

猜你喜欢

转载自www.cnblogs.com/iwehdio/p/12262864.html
今日推荐