java中的多线程问题

来源:互联网 发布:澳大利亚土木工程知乎 编辑:程序博客网 时间:2024/05/17 07:09

1.什么是进程,线程,多线程

进程是系统中正在运行的程序
线程是进程的执行单元,执行路径
多线程是多个线程并发执行的技术.

2.什么情况下使用多线程:

(1).单线程不能满足业务需要.比如火车票售票系统,在同一时间可能有多个请求,这些请求之间是相互独立的,没有依赖关系,后台必须通过多线程保证对用户的及时响应.
(2).单线程不能满足性能要求,通过多线程提高效率.比如,多线程可以用一个线程专门用于读写文件,其他的线程用于对读取数据进行处理,这样才有可能更好地利用 CPU 资源。

3.什么是线程安全

  
如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码,如果每次运行结果和单线程运行的结果是一样的,那就是线程安全的。如果运行结果和单线程的运行结果不同,就为线程不安全.

4.多线程的两种实现方式

(1)继承Thread,重写run()方法

public class MyThread extends Thread {    @Override    public void run() {        for (int x = 0; x < 100; x++) {                System.out.println(getName()+ x);        }    }}

(2)实现Runnable,重写run()方法

public class MyRunnable implements Runnable {    @Override    public void run() {        for (int x = 0; x < 100; x++) {        // getName()方法是Thread类的,而MyRunnable只实现了        Runnable接口,本身没有getName(),所以不能使用。                                                   System.out.println(Thread.currentThread().getName()                                 + "---hello"+ x);                }            }}一般使用第二种方式,因为方式一只能单继承,有一定的局限性,而方式二只创建一个对象,实现了数据和操作更好的分离.

5.通过火车票案例了解多线程(四个窗口同时出售火车票)

public class TicketRunnable implements Runnable {private static int tickets = 100;@Overridepublic void run() {    while (true) {        //通过加锁,保证线程安全        synchronized (this) {                if (tickets > 0) {                    try {                        Thread.sleep(100);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    System.out.println(Thread.currentThread().getName()                            + "正在出售第" + (tickets--) + "张票");                }                else {                    break;                }        }    }}}

主函数

public class RunnableTest {public static void main(String[] args) {    TicketRunnable tr = new TicketRunnable();    Thread t1 = new Thread(tr,"窗口1");    Thread t2 = new Thread(tr,"窗口2");    Thread t3 = new Thread(tr,"窗口3");    Thread t4 = new Thread(tr,"窗口4");    t1.start();    t2.start();    t3.start();    t4.start();}}注:(1).多线程中的锁对象可以为任意对象,但必须为同一对象    静态方法锁对象:是当前类的字节码文件对象   类名.class (2).解决线程同步问题的两种方式    a、同步代码块    synchronized(锁对象) {....}    //锁对象可以是任意类型    b、同步方法    格式:public synchronized 返回值 方法名(){....}    锁对象:this(3)如何判断线程是否安全     a、看有没有共享数据     b、看操作共享数据的语句是不是多条语句     c、看是不是在多线程的环境中

6.线程死锁问题

public class DieLock extends Thread {private boolean flag;public DieLock(boolean flag) {    this.flag = flag;}@Overridepublic void run() {    if (flag) {        synchronized (MyLock.objA) {             System.out.println("true -- objA");            synchronized (MyLock.objB) {                System.out.println("true -- objB");            }        }    } else {        synchronized (MyLock.objB) {            System.out.println("false -- objB");            synchronized (MyLock.objA) {                System.out.println("false -- objA");            }        }    }}}死锁原因总结     线程1自身拿着一个锁:A锁,线程2自身拿着一个锁:B锁     当线程1要用B锁,线程B要用A锁的时候就会发生死锁如何避免死锁:    不嵌套使用锁

7.线程的优先级

1、线程优先级级别 线程默认优先级是5。范围是1-10 Thread.MAX_PRIORITY         //10 Thread.MIN_PRIORITY         //1 Thread.NORM_PRIORITY     //52、方法 public final int getPriority():获取线程优先级 public final void setPriority(int newPriority):更改线程的优先级3、注意 优先级可以在一定的程度上,让线程获较多的执行机会4、举例 MyThread t = new MyThread(); System.out.println(t.getPriority()); t.setPriority(Thread.MAX_PRIORITY);

8.线程的等待唤醒机制

(1).前提: 两个线程共用一把锁,此时可以调用该锁的wait和notify方法,实现等待唤醒机制
(2)sleep和wait的区别
wait:是Object类的方法,可以不用传递参数,释放锁对象
sleep:是Thread类的静态方法,需要传递参数
案例:多线程实现设置和获取学生信息
Student类

public class Student {private String name;private int age;private boolean flag = false;public synchronized void set(String name, int age) {    // 如果有数据就等待    if (this.flag) {        try {            this.wait();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    // 设置值    this.name = name;    this.age = age;    // 修改标记    this.flag = true;    this.notify();}public synchronized void get() {    // 如果没有数据就等待    if (!this.flag) {        try {            this.wait();        } catch (InterruptedException e) {            e.printStackTrace();        }    }    // 获取值    System.out.println(this.name + "***" + this.age);    // 修改标记    this.flag = false;    this.notify();}}

SetStudent类

public class SetStudent implements Runnable {private Student s;public SetStudent(Student s) {    this.s = s;}@Overridepublic void run() {    int x = 0;    while (true) {        if (x % 2 == 0) {            s.set("林青霞", 26);        } else {            s.set("刘意", 29);        }        x++;    }}}

GetStudent类

public class GetStudent implements Runnable {private Student s;public GetStudent(Student s) {    this.s = s;}@Overridepublic void run() {    while (true) {        s.get();    }}}

StudentTest测试类

public class StudentTest {public static void main(String[] args) {    Student s = new Student();// 资源类    SetStudent ss = new SetStudent(s);    GetStudent gs = new GetStudent(s);    Thread t1 = new Thread(ss);    Thread t2 = new Thread(gs);    t1.start();    t2.start();}}
0 0
原创粉丝点击