java多线程复习

用户既可以使用计算机听歌,也可以使用它打印文件,而这些活动完全可以同时进行,这种思想放在java中被称为并发,而将并发完成的每一件事情称为线程。

实现线程的两种方式:
在java种主要提供两种方式实现线程,分别为继承java.lang.Thread类与实现java.lang.Runnable接口。
继承Thread类方式
首先需要定义的线程类继承Thread类,然后重写覆盖run()方法,run()方法中的代码就是线程索要完成的任务代码,然后在执行Thread中的start()方法执行线程,也就是调用run()方法。

代码示例:

package com.huangxt.thread;

/**
 * @Title: MyThread
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/7/11 16:25
 */
public class MyThread1 extends Thread{
    @Override
    public void run() {
        System.out.println("执行线程任务代码");
    }

    public static void main(String[] args) {
        Thread thread = new MyThread1();
        thread.start();
    }
}

“执行代码时控制台会打印出执行线程任务代码”

实现Runnable接口方式
当一个自定义的线程类已经继承了一个别的什么类,就不能再继承Thread类了,此时就可以实现Runnable接口一样的可以完成线程定义。
在源码中Thread也是实现了Runnable接口的。
实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。
Thread类中的两个构造方法:
1、public Thread(Runnable target)。
2、public Thread(Runnable target,String name)。
这两个构造方法的参数中都存在Runnable实例。使用这两个构造方法可以将Runnable实例与Thread相关联。

使用Runnable接口步骤如下,定义一个实现Runnable接口的类,并重写run()方法,该方法是和Thread类中的run()方法一样的都是线程任务的代码。然后再用Thread类的以上两个构造生成Thread对象,执行start()方法。

代码示例:

package com.huangxt.thread;

/**
 * @Title: MyRunnable
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/7/11 16:59
 */
public class MyRunnable implements Runnable{
    @Override
    public void run() {
        System.out.println("执行实现Runnable的线程任务代码");
    }

    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread = new Thread(myRunnable);
        thread.start();
    }
}

线程的生命周期
线程的生命周期有7种状态,分别是出生状态,就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态。
出生状态:就是线程被创建时处于的状态,在用户使用该线程实例调用start()之前都属于出生状态。
就绪状态:当执行start()方法后。
运行状态:当线程获得系统资源后就进入运行状态。
等待状态:在运行状态下调用wait()方法时,该线程便进入等待状态,进入等待状态的进程必须调用notify()方法才能被唤醒,而notifyAll方法时将所有处于等待状态的线程唤醒。
休眠状态:当线程调用Thread类的sleep()方法时,线程进入休眠状态。
阻塞状态:当线程运行状态时发出输入/输出请求,该线程进入阻塞状态。在其等待输入/输出完成进入就绪状态,对于阻塞的线程来说,即使系统资源空闲,线程依然不能回到运行状态。
死亡状态:当线程的run()方法执行完毕时,线程进入死亡状态。

线程的休眠
Thread.sleep(1000),sleep()是一个静态方法。

线程的加入
如果某程序为多线程程序,假如存在一个线程A,现在需要插入线程B,并要求线程B先执行完毕,然后在继续执行线程A,此时可以使用Thread类中的join()方法来完成。这就好比甲某正在看电视,突然有乙某上门收水费,甲某需要付完水费再继续看电视。

package com.huangxt.thread;

/**
 * @Title: JoinMothedTest
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/7/11 19:02
 */
public class JoinMothedTest {
    private Thread threadA = new Thread(new Runnable(){
        public void run(){
            System.out.println("开始交水费");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("完成交水费");
        }
    });
    private Thread threadB = new Thread(new Runnable(){
        public void run(){
            System.out.println("开始看电视");

            try {
                threadA.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("结束看电视");

        }
    });

    public static void main(String[] args) {
        JoinMothedTest joinMothedTest = new JoinMothedTest();
        joinMothedTest.threadB.start();
        joinMothedTest.threadA.start();

    }
}

线程的中断
以往有的时候回使用stop()方法停止线程,但当前版本的JDK早已废除了stop()方法,不建议使用stop()方法停止一个线程的运行。

可以设置是否符合条件结束线程。如下代码:

package com.huangxt.thread;

/**
 * @Title: StopThread
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/7/11 19:32
 */
public class StopThread implements Runnable{
    private  boolean isStop = false;
    @Override
    public void run() {
        while (true){
            //...
            if(isStop)
                break;
        }
    }

    public void setStop(){
        this.isStop = true;
    }
}

线程的礼让
在Thread类中提供了一种礼让方法,使用yield()方法表示,他只是给当前正处于运行撞他的线程一个提醒,告知它可以将资源礼让给其他线程,但这仅是一种暗示,没有任何一种机制保证当前线程会将资源礼让。
yeild()方法使具有同样优先级的线程有进入可执行状态的机会,当当前线程放弃执行权时会再度回到就绪状态,对于支持多任务的操作系统来说,不需要调用yield()方法,因为操作系统会为线程自动分配CPU时间片来执行。

线程的优先级
线程有优先级之说,如果有很多线程处于就绪状态,优先级越大的线程就越先执行进入运行状态,优先级越小的运行的几率较小。
在Thread中包含成员变量代表线程的某些优先级,如MIN_PRIORITY等于1,NORM_PRIORITY等于5,MAX_PRIORITY=10。

线程优先级可以使用setPriority()方法调整,如果设置的优先级不在1~10之内,将产生IllegalArgmentException异常。

package com.huangxt.thread;

/**
 * @Title: Priority
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/7/11 20:06
 */
public class Priority {
    public static void main(String[] args) {
        Thread thread1 = new MyThread1();
        Thread thread2 = new MyThread1();
        Thread thread3 = new MyThread1();
        Thread thread4 = new MyThread1();

        thread1.setPriority(8);
        thread2.setPriority(8);
        thread3.setPriority(4);
        thread4.setPriority(1);
    }
}

线程安全
何为线程安全?好比两个线程同时抢占资源的冲突,线程安全问题源于两个或者多个线程同时存取单一对象的数据。比如售票系统。
不处于线程安全问题票取到后面可能变成负数。如下代码:

package com.huangxt.thread;

/**
 * @Title: TestThread
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/6/21 15:28
 */
public class TestThread implements Runnable{
    int num = 10;
    @Override
    public void run() {
        while (true){
            //synchronized ("") {
                if (num > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }

                System.out.println("tickets" + --num);
           // }
        }
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        Thread threadA = new Thread(testThread);
        Thread threadB = new Thread(testThread);
        Thread threadC = new Thread(testThread);
        Thread threadD = new Thread(testThread);
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
    }

}

为了处理线程安全问题引出了线程同步机制
1、同步块
在java中提供了同步机制,可以有效地防止资源冲突。同步机制使用synchronized关键字。
同步块(同步代码块)语法:

synchronized(Object){
}

实例代码:

package com.huangxt.thread;

/**
 * @Title: TestThread
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/6/21 15:28
 */
public class TestThread implements Runnable{
    int num = 10;
    @Override
    public void run() {
        while (true){
            synchronized ("") {
                if (num > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }

                System.out.println("tickets" + --num);
            }
        }
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        Thread threadA = new Thread(testThread);
        Thread threadB = new Thread(testThread);
        Thread threadC = new Thread(testThread);
        Thread threadD = new Thread(testThread);
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
    }
}

2、同步方法
同步方法就是在方法前面修饰synchronized关键字的方法,语法如下:

synchronized void function(){}

当某对象调用同步方法时,该对象的其他同步方法需要等待该同步方法执行完后才能被执行。

实例:

package com.huangxt.thread;

/**
 * @Title: TestThread
 * @Description:
 * @Auther: huangxt
 * @Version: 1.0
 * @create 2019/6/21 15:28
 */
public class TestThread implements Runnable{
    int num = 10;
    @Override
    public void run() {
        doit();
    }

    public synchronized void doit(){
        while (true){
            synchronized ("") {
                if (num > 0) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else{
                    break;
                }

                System.out.println("tickets" + --num);
            }
        }
    }

    public static void main(String[] args) {
        TestThread testThread = new TestThread();
        Thread threadA = new Thread(testThread);
        Thread threadB = new Thread(testThread);
        Thread threadC = new Thread(testThread);
        Thread threadD = new Thread(testThread);
        threadA.start();
        threadB.start();
        threadC.start();
        threadD.start();
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值