day21-多线程

一、线程与进程

1.进程:正在执行的程序(QQ.exe),表示一个可执行程序一次的执行过程。

2.进程的三种基本状态。

 (1).就绪状态:

           当进程分配到了所需要的所有资源后,等待CPU的资源时(表示具有的cpu的执行资格,但还没有获得cpu的执行权),此时只要获得了cpu的资源后,便可执行,这样的进程状态就称为就绪状态。通常一个系统中就绪状态的进程有多个,通常他们会排成一个队列,成为就绪队列。

  (2)执行状态:

           就绪队列中进程已经获得了cpu的资源,拿到了cpu的执行权,通过处理机调度,该进程就可以执行了。在单处理机系统中,只有一个进程处于执行状态;多处理机系统中,可以有多个进程处于执行状态。

  (3)阻塞状态:

          正在执行的进程因某些其他事情暂时无法继续执行时候,(通常是正在执行的进程遇到了I/O请求时候),便进入阻塞状态。

进程三种状态转换图:

3.线程:

    通俗理解就是:每一个进程在执行的时候,可以做很多不同的事情,那每一件事都是由一个线程来执行的任务,这就是线程。

(1).线程的创建方法

    -a .继承Thread类,重写run()方法。

// 自定义类继承Thread
public class MyThread extends Thread {
    // 使用带名称的构造方法
    public MyThread(String name) {
        // 调用父类的构造方法
        super(name);
    }
    // 重写run方法
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(this.getName() + ":" + i);
        }
    }
}

// 测试
public class ThreadTest { public static void main(String[] args) { MyThread myThread1 = new MyThread("线程1"); // 启动线程 myThread1.start(); MyThread myThread2 = new MyThread("线程2"); // 启动线程 myThread2.start(); } }

    -b.实现Runnable接口,重写run()方法。

// 自定义类实现Runnable接口
public class MyRunnable implements Runnable {
    // 重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            // 获得当前线程的名称
            System.out.println(Thread.currentThread().getName() + ":" + i);
        }
    }
}

public class RunnableTest {

    public static void main(String[] args) {
        MyRunnable myRunnable1 = new MyRunnable();
        MyRunnable myRunnable2 = new MyRunnable();
        // 调用相应的构造方法,指定线程名
        Thread thread1 = new Thread(myRunnable1, "线程1");
        // 启动线程
        thread1.start();
        // 调用相应的构造方法,指定线程名        
        Thread thread2 = new Thread(myRunnable2, "线程2");
        // 启动线程
        thread2.start();
    }
}

    -c.匿名内部类形式,直接new一个Thread,里面重写run()方法。或者new一个Thread,里面再new一个Runnable,重写run()方法。

   ThreadInner:

public
class ThreadInner { public static void main(String[] args) { // 使用匿名内部类实现线程执行具体内容 new Thread("新线程") { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(this.getName() + ":" + i); } } // 启动线程 }.start(); } }
   RunnableInner :

public
class RunnableInner { public static void main(String[] args) { // 实例化线程 new Thread(new Runnable() { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(Thread.currentThread().getName() + ":" + i); } } // 启动线程 }, "新线程").start(); } }

(2).线程的常用方法:

 1).设置线程名称

 setName(String name);

 Thread(String name);

  2).设置线程休眠状态

  sleep(long millis):此时线程会进入阻塞状态,时间到了自动唤醒就绪执行。

  3).等待某一线程终止后,再执行其他线程

  join()方法,线程开启后,调用该方法的线程,会是的其他线程等待它执行完毕后再执行其他的。

   4).设置线程的优先级

    setPriority(int newPriority) 参数范围:1-10,在开启线程之前执行(调用start()之前)。但是这个仅仅是提升线程获得cpu时间片的概率,并不能一定保证优先执行。

  5).设置后台线程

    setDaemon(booolean on): 后台线程也称守护线程,比如jvm的垃圾回收线程,在开启线程之前执行。设置完毕后,表示该线程会随着前台线程都死亡后,会自动死亡。

 

   (3).java中的线程的生命周期。

   - 新生(创建):实例化一个线程对象。

   - 就绪:准备执行了,暂时还没有分配到cpu的时间片(cpu执行权)

   - 运行:分配到了时间片,执行相关任务。

   - 阻塞:由于某些原因导致暂时不能继续执行下去,此时进入阻塞,等待某些原因解除后,可以进入就绪状态

   - 消亡:线程结束(stop方法可以强制结束,不建议)

   线程状态图:

 

 

4.多线程同步问题

  当我们多个线程去访问同一个资源的时候,如果不同步,就会出现多个线程访问的资源并不一致的情况。比如售卖火车票,如果仅仅有100张票,在不同步的情况下,A B C D 同时进来看都有100张,每人都可以买100张,那实际就需要400张来满足需求,实际情况并不能这样子。所以需要同步(加锁)。在A进来的时候,B是不可以进来的。只有等A完毕后,资源释放了其他的才可以进来。

代码:

public class Ticket implements Runnable {

    // 使用private定义竞争资源
    private int ticket = 100;

    @Override
    public void run() {
        while (true) {
            // 对当前线程进行同步加锁
            synchronized (this) {
                ticket--;
                // 当车票售空时跳出循环
                if (ticket < 0) {
                    break;
                }
                System.out.println(Thread.currentThread().getName() + "购买,当前剩余票数:" + ticket);
            }
        }
    }
}
public class TicketTest {
    // 模拟两名旅客的抢票
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread thread1 = new Thread(ticket,"旅客1");
        Thread thread2 = new Thread(ticket,"旅客2");
        thread1.start();
        thread2.start();
    }
}

经典案例 生产者-消费者问题 值得考虑。

 

          

posted on 2018-08-11 11:28  志爱007  阅读(117)  评论(0编辑  收藏  举报