Java自学习记录-多线程

184 阅读1分钟

线程与进程

进程是一个程序动态执行的过程,一个程序动态执行的过程,可以同时执行多个线程。

继承Thread类

一个类只要继承了Thread类,就是多线程操作类。在Thread子类中,必须明确覆盖了Thread类中的Run方法,此方法为线程的主体。

// 线程类
public class Student extends Thread {
    private String name;
    Student(String name){
        this.name = name;
    }
    public static void main(String args[]) {

    }
    public void run() {
        for (int i = 0;i<10;i++) {
            System.out.println(name+"运行,i="+i);
        }
    }
}
// 测试类
public class demo1 {

    public static void main(String args[]) {
        Student stu = new Student("线程A");
        Student stu2 = new Student("线程B");
        stu.run();
        stu2.run();
    }
}
// 输出结果
线程A运行,i=0
线程A运行,i=1
线程A运行,i=2
线程A运行,i=3
线程A运行,i=4
线程A运行,i=5
线程A运行,i=6
线程A运行,i=7
线程A运行,i=8
线程A运行,i=9
线程B运行,i=0
线程B运行,i=1
线程B运行,i=2
线程B运行,i=3
线程B运行,i=4
线程B运行,i=5
线程B运行,i=6
线程B运行,i=7
线程B运行,i=8
线程B运行,i=9

编译程序执行完之后,先执行了stu对象后执行stu2对象,他们是顺序执行,这时候线程还没有启动,正确的启动线程我们不能再执行run()方法,应到执行start()方法

   public static void main(String args[]) {
        Student stu = new Student("线程A");
        Student stu2 = new Student("线程B");
        stu.start();
        stu2.start();
    }
    // 输出结果
    线程A运行,i=0
线程A运行,i=1
线程B运行,i=0
线程A运行,i=2
线程B运行,i=1
线程A运行,i=3
线程B运行,i=2
线程A运行,i=4
线程B运行,i=3
线程A运行,i=5
线程B运行,i=4
线程A运行,i=6
线程B运行,i=5
线程A运行,i=7
线程B运行,i=6
线程A运行,i=8
线程B运行,i=7
线程A运行,i=9
线程B运行,i=8
线程B运行,i=9

实现Runnable接口

如果继承Thread来实现多线程,java是单继承,处理业务代码会有限制性,所以我们可以使用Runnable来实现多线程。

/// 使用接口Runnable
public class Student implements Runnable {
    private String name;
    Student(String name){
        this.name = name;
    }
    public static void main(String args[]) {

    }
    public void run() {
        for (int i = 0;i<10;i++) {
            System.out.println(name+"运行,i="+i);
        }
    }
}
/// 执行
public class demo1 {

    public static void main(String args[]) {
        Student stu = new Student("线程A");
        Student stu2 = new Student("线程B");
        Thread t = new Thread(stu);
        Thread t1 = new Thread(stu2);
        t.start();
        t1.start();
    }
}
// 输出结果
线程B运行,i=0
线程B运行,i=1
线程B运行,i=2
线程B运行,i=3
线程B运行,i=4
线程B运行,i=5
线程B运行,i=6
线程B运行,i=7
线程B运行,i=8
线程B运行,i=9
线程A运行,i=0
线程A运行,i=1
线程A运行,i=2
线程A运行,i=3
线程A运行,i=4
线程A运行,i=5
线程A运行,i=6
线程A运行,i=7
线程A运行,i=8
线程A运行,i=9

线程状态

1.创建线程状态

Thread thread = new Thread()

2.就绪状态,具备运行条件

thread.start()

3.运行状态

thread.run()

4.阻塞状态

thread.sleep()
thread.supsend()
thread.wait()

5.死亡状态

thread.stop()
thread.run()--- 结束后

线程操作的相关方法

// 构造方法 接受Runnable接口子类
Thread t = new Thread(Runnable target);
// 构造方法 接受Runnable接口子类,设置线程名称
Thread t = new Thread(Runnable target,String name);
// 实例化Thread对象
Thread t = new Thread(String name);	
// 返回当前执行的线程
public static Thread currentThread() {
return null;
}
// 获取线程名称
public final String getName();
// 返回优先级
public final int getPriority();
// 返回线程是否被中断
public boolean isInterrupted();
// 判断线程是否还在活跃
public final boolean isAlive();
// 等待线程死亡
public final void join() throws InterruptedException{};
// 等待多少毫秒后,线程死亡
public  final  synchronized void  join(long millis) throws  InterruptedException {}
// 执行线程
public void run()
// 设置修改线程名
public final setName(String name)
// 设置线程优先级
public final setPriority(int priority)
// 使正在执行的线程睡眠多少毫秒
public  static  void sleep(long millis) throws InterruptedException {}
// 开始执行线程
public void start()
// 返回代表线程的字符串
public String toString()
// 暂停该线程容许其他线程执行
Thread.yield();
// 让该线程后台挂起
public final void setDaemon(boolean on);

同步与死锁

一个多线程程序如果是通过Runnable,就会造成同一属性多个线程同时访问的同一个属性,导致数据有问题。

public class Student implements Runnable {

    private int ticket = 5;
    public void run() {
        for (int i = 0;i<100;i++) {
            if (ticket>0) {
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("售出一张票,还剩余"+ticket--);
            }
        }
    }
}
public static void main(String args[]) {
        Student stu = new Student();
        Thread t = new Thread(stu);
        Thread t1 = new Thread(stu);
        Thread t2 = new Thread(stu);
        t.start();
        t1.start();
        t2.start();
    }
    // 输出结果
售出一张票,还剩余5
售出一张票,还剩余4
售出一张票,还剩余3
售出一张票,还剩余2
售出一张票,还剩余1
售出一张票,还剩余0
售出一张票,还剩余-1

public void run() {
        for (int i = 0;i<100;i++) {
            synchronized (this) {
            if (ticket>0) {
                   try {
                       Thread.sleep(300);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println("售出一张票,还剩余"+ticket--);
               }
            }
        }
    }
// 输出结果
售出一张票,还剩余5
售出一张票,还剩余4
售出一张票,还剩余3
售出一张票,还剩余2
售出一张票,还剩余1