[java]9、多线程

2021-10-08  本文已影响0人  史记_d5da

1、开启新线程

1)、创建一个Thread类的子类
2)、在Thread类的子类中重写Thread类中的run方法,设置线程任务(开启线程要做什么?)

public class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i <20 ; i++) {
            System.out.println("run:"+i);
        }
    }
}
线程执行原理

2、线程名称

public class MyThread extends Thread{
    // 设置线程名称
    public MyThread(String name) {
        super(name);
    }

    @Override
    public void run() {
        // 获取线程名称
        System.out.println(getName());
        System.out.println(Thread.currentThread().getName());
    }
}

3、创建线程的第二种方式

public class RunnableImpl implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

// 启动线程
RunnableImpl run = new RunnableImpl();
Thread t = new Thread(run);
t.start();

实现Runnable接口创建多线程的好处
1)、避免了单继承的局限性,一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类,实现了Runnable接口,还可以继承其他类,实现其他接口
2)、增强了程序的扩展性,降低了程序的耦合性

4、线程同步

1)、synchronized实现线程同步锁
2)、静态代码块实现多线程 同步

private int ticket = 100;
/* 同步方法的锁对象,new RunnableImp() 也就是this*/
public synchronized void payTicket() {
//    synchronized (this) {
      System.out.println(Thread.currentThread().getName() + "正在卖第:" + ticket + "张票");
      ticket--;
//    }
}
private static int ticket = 100;
/* 静态方法的锁对象是本类的class属性 */
public static synchronized void payTicket() {
    System.out.println(Thread.currentThread().getName() + "正在卖第:" + ticket + "张票");
    ticket--;
}

3)、lock实现锁

public class RunnableImp implements Runnable {
    Lock l = new ReentrantLock();
    private int ticket = 100;

    @Override
    public void run() {
        while (ticket > 0) {
            l.lock();
            if (ticket > 0) {
                try {
                    Thread.sleep(10);
                    System.out.println(Thread.currentThread().getName() + "正在卖第:" + ticket + "张票");
                    ticket--;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally { // 无论程序是否发生异常,都会把锁对象释放
                    l.unlock();
                }
            }
        }
    }
}

5、线程状态

线程状态

使用Object的 wait() 和 notify()实现生产者和消费者关系

public class Demo10 {
    public static void main(String[] args) {
        // 创建锁对象,保证唯一
        Object obj = new Object();
        new Thread() {
            @Override
            public void run() {
                // 保证等待和唤醒的线程只能有一个执行,需要同步机制
                synchronized (obj) {
                    System.out.println("告知老板要的包子的种类和数量");
                    try { // 调用wait 进入等待状态
                        obj.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 唤醒之后的代码
                    System.out.println("包子做好了,开吃");
                }
            }
        }.start();
        // 创建一个老板线程
        new Thread(){
            @Override
            public void run() {
                // 花了5s做包子
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (obj) {
                    System.out.println("老板5s之后做好包子,告知顾客,可以吃包子");
                    // 唤醒顾客吃包子
                    obj.notify();
                    // notifyAll(); 唤醒所有等待线程
                }
            }
        }.start();
    }
}

6、线程池

// RunnableImpl 
public class RunnableImpl implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}
// ----------------------------------------------------------------------
// main 
// 使用线程池的工厂类 Executors里面提供的静态方法newFixedThreadPool 产生指定数量的线程池
ExecutorService es = Executors.newFixedThreadPool(2);
// 调用ExecutorService中的方法submit,传递线程任务,开启线程,执行run方法
es.submit(new RunnableImpl()); // pool-1-thread-1
es.submit(new RunnableImpl()); // pool-1-thread-2
// 线程池会一直开启,使用完了线程,会自动把线程归还给线程池,线程可以继续使用
es.submit(new RunnableImpl()); // pool-1-thread-2
// 调用shutdown销毁线程池(线程池销毁,不建议使用)
es.shutdown();
上一篇下一篇

猜你喜欢

热点阅读