JavaSE基础之多线程

        进程与线程:一个进程可以启动多个线程

1.创建线程的两种方法

        a.继承java.lang.Thread类,重写run()方法,该方法相当于程序的入口,最后在通过线程对象.start()方法启动线程

public class Test_01 {
    public static void main(String[] args) {

        // 创建线程对象(继承)
        Thread thread = new Processor();

        // 启动线程
        thread.start();
    }
}

class Processor extends Thread {//继承创建线程
    @Override
    public void run() {
        play();
    }

    public void play() {
        for (int i = 0; i < 10; i++) {
            System.out.println("继承Thread的线程启动了:" + i);
        }
    }
}

        b.实现java.lang.Runnable接口,再实现run()方法,最后在用线程对象调用start()方法启动线程

public class Test_01 {
    public static void main(String[] args) {

        // 创建线程对象(实现)
        // new Thread(Runnable target)
        Thread thread = new Thread(new Processor());

        // 启动线程
        thread.start();
    }
}

class Processor implements Runnable {//实现Runnable接口

    @Override
    public void run() {
        play();
    }

    public void play() {
        for (int i = 0; i < 10; i++) {
            System.out.println("实现Runnable的线程启动了:" + i);
        }
    }
}

2.线程的生命周期:

        新建:new语句创建完成时

        就绪:执行start()之后

        运行:占用CPU时

        阻塞:执行wait()语句后或执行sleep()语句后或等待某个对象锁时

        终止:run()执行完成

3.线程的控制方法:

        a.join():当前线程与指定线程合并,与其他线程无关

 public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Processor5();
        Thread t2 = new Processor5();
        t1.setName("t1");
        t2.setName("t2");
        t1.start();
        t2.start();

        /**
         * 调用某线程的该方法,将当前线程与该线程"合并"
         * 即等待该线程结束后,再回复当前线程的运行
         */
        t1.join(); // 让当前main线程等待t1线程执行完后再执行

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "-->" + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
}

        b.yield():暂停当前正在执行的线程,让其他线程执行(写在那个线程中,就暂停哪个线程)

    public static void main(String[] args) {

        Thread t1 = new Process6();
        t1.setName("t1");
        t1.start();

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + i);
            if (i % 2 == 1) {
                // 当i为奇数时,暂停main线程,让t1线程优先执行
                Thread.yield();
            }
        }
    }

        c.sleep():让当前线程睡眠,写在哪个线程就睡眠哪个线程

                唤醒线程:1)正常唤醒(睡眠时间到了)        2)异常唤醒: 线程对象.interrupt();

public class _03_Interrupt {
    public static void main(String[] args) {

        Thread thread = new Thread(new Processor4());
        // setName():设置线程名
        thread.setName("t1");
        thread.start();
        
        /**
         * main线程睡眠1s,而t1线程睡眠3s
         * 
         * 所以结果为t1是属于异常唤醒
         */
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 异常唤醒
        thread.interrupt();
    }
}

class Processor4 implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(3000);
            System.out.println("睡醒了...");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("异常唤醒...");
        }
        System.out.println("-----------");
    }
}

        c.setDaemon(boolean flag):设置一个指定的守护线程

        Thread t1 = new Processor10();
        // 把t1设置成守护线程,会随着主线程而死亡
        t1.setDaemon(true);
        t1.setName("t1");
        t1.start();

        /**
         * 由于主线程main执行了5次,所以守护线程t1也循环5次结束
         */
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + "-->" + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        d.

           wait():该线程进入等待状态,如果被唤醒之后,接着当前等待的地方继续执行(用于成员方法中)

           notify():随机唤醒一个在该对象上等待的线程

           notifyAll():唤醒所有在该对象上等待的线程

4.锁(Lock与Synchronized)

        Lock:块锁,可以锁住任意行代码

    //创建锁
    Lock lock = new ReentrantLock();

    修饰符 返回值类型 方法名(参数列表) {

        // 开启同步
        lock.lock();

        /**
         * 需要上锁的同步代码
         */

        // 取消同步
        lock.unlock();

    }

        Synchronized:

                注:

                        如果访问了一个类的加锁的静态方法的时候,该类所有加着synchronized修饰的静态方法,全部被锁定

public class _11_Synchronized {
    public static void main(String[] args) {

        Thread t1 = new Processor11();
        Thread t2 = new Processor11();
        Thread t3 = new Processor11();

        t1.setName("t1");
        t2.setName("t2");
        t3.setName("t3");

        t1.start();
        t2.start();
        t3.start();
    }
}

class Processor11 extends Thread {
    /**
     * 运行结果:<br>
     * m3执行了<br>
     * m1执行了<br>
     * m2执行了
     */
    @Override
    public void run() {
        //m1,m2均被synchronized修饰,所以访问m1时,m2也会被锁定
        if ("t1".equals(Thread.currentThread().getName())) {
            Processor11.m1();
        } else if ("t2".equals(Thread.currentThread().getName())) {
            Processor11.m2();
        } else if ("t3".equals(Thread.currentThread().getName())) {
            Processor11.m3();
        }
    }
    
    //类中加锁的静态方法
    public synchronized static void m1() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("m1执行了");
    }

    //类中加锁的静态方法
    public synchronized static void m2() {
        System.out.println("m2执行了");
    }

    //类中未加锁的静态方法
    public static void m3() {
        System.out.println("m3执行了");
    }
}

                        如果访问了一个对象的加锁的成员方法的时候,该对象所有加着synchronized修饰的成员方法,都会锁定

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值