xiaoqiyan 的个人博客

记录精彩的程序人生

Open Source, Open Mind,
Open Sight, Open Future!
  menu
15 文章
0 评论
7238 浏览
0 当前访客
ღゝ◡╹)ノ❤️

Java学习之第6章 多线程

第6章 多线程

指在软件或者硬件上实现多个线程并发执行的技术

6.2 线程的创建

两种方式:

  1. 继承thread类
  2. 实现runnable接口

6.2.1 继承Thread类

package example01;

public class ThreadDemo extends Thread {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("ThreadDemo类的run方法执行了");
        }
    }
}

创建测试类

package example01;

public class Example01 {
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        threadDemo.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主方法main()执行了");
        }
    }
}

6.2.2 实现Runnable接口

package example02;

public class ThreadDemo implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("ThreadDemo类的run方法执行了");
        }
    }
}
package example02;

public class Example02 {
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        Thread thread = new Thread(threadDemo);
        thread.start();
        for (int i = 0; i < 5; i++) {
            System.out.println("主方法main()执行了");
        }
    }
}

6.2.3 两种方式的对比

package example03;

public class Ticket extends Thread {
    private int tickets = 100;
    private String name;

    public Ticket(String name) {
        this.name = name;
    }

    public void run() {
        while (true) {
            if (tickets > 0) {
                System.out.println(name + "正在发售第" + tickets-- + "车票");
            } else {
                break;
            }
        }
    }
}
package example03;

public class Example03 {
    public static void main(String[] args) {
        Ticket t1 = new Ticket("窗口1");
        Ticket t2 = new Ticket("窗口2");
        Ticket t3 = new Ticket("窗口3");
        Ticket t4 = new Ticket("窗口4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

这样子没有共享100张票,每个线程都在处理各自的资源,是不对的

package example04;

public class Ticket implements Runnable {
    private int tickets = 100;

    public void run() {
        while (true) {
            if (tickets > 0) {
                String name = Thread.currentThread().getName();
                System.out.println(name + "正在发售第" + tickets-- + "车票");
            } else {
                break;
            }
        }
    }
}
package example04;

public class Example04 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread t1 = new Thread(ticket, "窗口1");
        Thread t2 = new Thread(ticket, "窗口2");
        Thread t3 = new Thread(ticket, "窗口3");
        Thread t4 = new Thread(ticket, "窗口4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

Runnable接口的优势:

  1. 适合多个程序代码相同的线程处理同一资源的情况
  2. 可以避免使用Java的单继承特性带来的局限
  3. 建议使用这种

6.3 线程的状态和转换

线程的5种状态

新建

​ 仅仅在Java虚拟机中分配了内容空间,还不能运行

就绪

​ 进入运行池,等待调度

运行

​ 调度开始运行

阻塞

​ 等待某个事件或操作是进入阻塞状态

死亡

在操作系统中学过

6.4 多线程同步

限制某个资源在某一时刻只能被一个线程访问

6.4.1 线程安全

package example05;

public class Ticket implements Runnable {
    private int tickets = 100;

    public void run() {
        while (true) {
            synchronized (this) {
                try {
                    if (tickets > 0) {
                        Thread.sleep(10);
                        String name = Thread.currentThread().getName();
                        System.out.println(name + "正在发售第" + tickets-- + "车票");
                    } else {
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
package example05;

public class Example05 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        Thread t1 = new Thread(ticket, "窗口1");
        Thread t2 = new Thread(ticket, "窗口2");
        Thread t3 = new Thread(ticket, "窗口3");
        Thread t4 = new Thread(ticket, "窗口4");
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}

加入了线程睡眠和同步代码块

6.4.3 同步方法

也可以只用synchronized关键字将一个方法修饰成同步方法,效果和上面代码块一样

package example06;

public class Ticket implements Runnable {
    private int tickets = 100;

    public void run() {
        while (true) {
            saleTicket();
            if (tickets <= 0) {
                break;
            }
        }
    }

    private synchronized void saleTicket() {
        if (tickets > 0) {
            try {
                Thread.sleep(10);
                String name = Thread.currentThread().getName();
                System.out.println(name + "正在发售第" + tickets-- + "车票");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

同步方法的锁是当前调用该方法的对象,也就是this指向的对象


标题:Python
作者:肖祺彦
地址:url

评论
取消