java线程--Java笔记

目录

线程

 一.线程的使用

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

2.实现 Runnable 接口 ,重写 run 方法

二.线程的常用方法

1.       1--4

2.    5

3. 6--9

 4.10--11

5.用户线程和守护线程

三.线程的状态

四.Synchronized

1.线程同步机制

2.互斥锁

3.释放锁

4.死锁


线程

进程:指运行中的程序,进程是程序的一次执行过程(正在运行的一个程序)

线程:线程由进程创建,一个进程可以拥有多个线程

①.单线程:同一个时刻,只执行一个线程

②.多线程:同一个时刻,执行多个线程(同时下载歌曲、视频)

③.并发:同一个时刻,多个线程交替执行(开车时打电话,其实是大脑在切换)

④.并行:同一个时刻,多个线程同时执行(一边上厕所一边玩手机)

 一.线程的使用

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

一个类继承 Thread 类,该类就可以当作线程使用,重写 run()方法

        new App().new A().start();

        for (int i = 5; i < 10; i++) {
            System.out.print("11111" + "\t");
            Thread.sleep(500);
        }
    }

    class A extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("22222");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

输出:

2.实现 Runnable 接口 ,重写 run 方法

java 是单继承的,在某些情况下一个类可能已经继承了 一个 父类,这时再继承Thread 类显然是不可能的

实现 Runnable 接口的类实例化之后,是没有 start()方法的,需要创建一个 Thread 对象,

然后把 实现 Runnable 接口的类当作参数 传进去

        Thread t = new Thread(new App().new A());
        t.start();

        for (int i = 0; i < 5; i++) {
            System.out.print("11111" + "\t");
            Thread.sleep(500);
        }
    }

    class A implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("22222");
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

输出: 

二.线程的常用方法

1.setName()设置线程名称
2.getName()返回线程名称

3.setPriority()更改线程的优先级(范围在 1--10 )

①.MIN_PRIORITY = 1

②.NORM_PRIORITY = 5

③.MAX_PRIORITY = 10

4.getPriority()获取线程的优先级
5.run()调用线程对象的 run()方法
6.start()是线程开始执行,调用 start0()
7.slee()让指定的线程休眠
8.interrupt()中断线程(休眠中的线程)
9.Thread.currentThread () 主线程
10.yield()礼让线程(时间不确定也不一定礼让成功)
11.join()线程插队

1.       1--4

        A a = new App().new A();

        // 1.setName()设置线程名称
        a.setName("张三");

        // 2.getName()返回线程名称
        System.out.println(a.getName());
        
        // 3.setPriority()更改线程的优先级
        a.setPriority(Thread.MIN_PRIORITY);

        // 4.getPriority()获取线程的优先级
        System.out.println(a.getPriority());

输出:

2.    5

调用 run()方法并不能实现多线程,它只能按顺序输出

        A a1 = new App().new A();

        // 5.run()调用线程对象的 run()方法
        a1.run();

        System.out.print(Thread.currentThread().getName() + "\t");
        System.out.println("1000");

输出:

 

3. 6--9

        A a1 = new App().new A();

        // 6.start()是线程开始执行,调用 start0()
        a1.start();

        for (int i = 0; i < 5; i++) {
            // 9.Thread.currentThread () 主线程
            System.out.print(Thread.currentThread() + "\t");
            System.out.println(i);
            // 7.slee()让指定的线程休眠
            Thread.sleep(1000);
        }
        // 8.interrupt()中断线程(休眠中的线程)
        a1.interrupt();//打醒
    }
    class A extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.print(getName() + "\t");
                System.out.println(i);
                if (i == 2) {//休眠 20 秒
                    try {
                        Thread.sleep(20000);
                    } catch (InterruptedException e) {
                        System.out.println("aaaaa");
                    }
                }
            }
        }
    }

输出:

 

 4.10--11

start()调用了start0()

        A a1 = new App().new A();
        a1.start();

        for (int i = 0; i < 5; i++) {
            System.out.print(Thread.currentThread().getName() + "\t");
            System.out.println(i);
            if (i == 3) {
                // 11.join()线程插队
                a1.join();
            }
        }
    }

    class A extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.print(getName() + "\t");
                System.out.println(i);
                if (i == 1) {
                // 10.yield()礼让线程(时间不确定也不一定礼让成功)
                Thread.yield();
                }
            }
        }
    }

输出: 

 

5.用户线程和守护线程

setDaemon() 设置守护线程

①.用户线程:也叫工作线程,当线程的任务执行完或通知结束

②.守护线程:为工作线程服务,当所有的工作线程结束 ,守护线程自动结束(垃圾回收机制为守护线程)

        A a1 = new App().new A();
        a1.setDaemon(true);
        a1.start();

        for (int i = 0; i < 2; i++) {
            System.out.print(Thread.currentThread().getName() + "\t");
            System.out.println(i);
        }
    }

    class A extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.print(getName() + "\t");
                System.out.println(i);
            }
        }
    }

输出:

 

三.线程的状态

1.new:线程未开启时。创建线程对象没有 start()开始前

2.RUNNABLE:正在运行时。运行 strat 方法后

3.BLOCKED:阻塞状态,等待进入同步代码块的锁时
4.WAITING:等待状态。执行 wait()、join()、park()后
5.TIMED_WAITING:超时等待状态。WAITING 里方法加上sleep()
6.TERMINATED:终止状态(线程结束时)。线程运行完成、被打断、被中止

示意图:

 

四.Synchronized

1.线程同步机制

在多线程中,一些敏感数据不允许被多个线程同时访问,这时候就需要同步来保证数据在一个时刻只能由一个线程访问。

当有一个线程在对内存进行操作时,其他线程不可以对这个内存地址进行操作,直到这个线程完成操作,其他线程才可以进入

2.互斥锁

①.来保证共享数据的完整性

②.当某个对象用 Synchronized 修饰时,表面在同一时刻只能由一个线程访问

③.程序执行效率会变低

④.同步方法(非静态)的锁默认是 this ,也可以是其他对象

⑤.同步方法(静态的)的锁为当前类本身,类.class

同步方法

        A a1 = new App().new A();
        new Thread(a1).start();
        new Thread(a1).start();
        new Thread(a1).start();
}
    class A implements Runnable {
        private int j = 10;
        boolean q = true;

        public synchronized void a() {
            if (j <= 0) {
                q = false;
                return;
            }
            System.out.print(Thread.currentThread().getName() + "\t");
            System.out.println(j--);
        }
        @Override
        public void run() {
            while (q) {
                a();
            }
        }
    }

输出:

 

 

同步代码块

 


        A a1 = new A();
        new Thread(a1).start();
        new Thread(a1).start();
        new Thread(a1).start();
    }
}

class A implements Runnable {
    static private int j = 10;
    static boolean q = true;

    public static void a() {
        synchronized (A.class) {
            if (j <= 0) {
                q = false;
                return;
            }
            System.out.print(Thread.currentThread().getName() + "\t");
            System.out.println(j--);
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    @Override
    public void run() {
        while (q) {
            a();
        }
    }
}

输出: 

 

3.释放锁

释放锁的情况

①.当前线程的同步方法或同步代码块 :执行结束

②.当前线程的同步方法或同步代码块 :遇到 break、return

③.当前线程的同步方法或同步代码块 :出现了未处理的 Error 或 Exception,导致异常非正常结束

④.当前线程的同步方法或同步代码块  :执行了 wait(),线程暂停

 不会释放锁的情况

①.线程执行同步方法或同步代码块时:程序调用了 sleep()、yield()方法,暂停当前线程

②.线程同步代码块时,其他线程调用了该线程的 suspend() 方法时该线程挂起

 

4.死锁

一个线程等待资源时,该资源被另一个线程所占用时,会导致死锁

        new Thread(new A(true)).start();
        new Thread(new A(false)).start();
    }
}

class A implements Runnable {

    static Object o1 = new Object();//静态成员是共享的
    static Object o2 = new Object();
    boolean b;

    public A(boolean b) {
        this.b = b;
    }

    @Override
    public void run() {
        if (b) {
            synchronized (o1) {
                System.out.println("o1");
                synchronized (o2) {
                    System.out.println("o2");
                }
            }
        } else {
            synchronized (o2) {
                System.out.println("o2");
                synchronized (o1) {
                    System.out.println("o1");
                }
            }
        }
    }
}

卡死了(你先给我,不你先给我)

输出:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值