线程

1.进程概述

进程简单来说就是计算机运行的一个程序

2.线程概述

线程是进程运行的最小单元,或者说是线程是进程的一条执行路径。一个进程至少包含一个线程,如果一个进程包含多个线程,则称为多线程应用程序。例如百度云,可同时下载多个内容。
主线程:jvm运行程序会创建一个main线程(主线程),该线程负责执行main方法。
子线程:线程并不是孤立的,而是相互联系。假设在A线程中创建了B线程, 习惯上称A线程为父线程, 称B线程为子线程。
串行:

在这里插入图片描述

并发:

在这里插入图片描述

并行:

在这里插入图片描述

3创建线程
3.1创建线程的两种方法
1)一个是定义Thread类的子类
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo01 {
    public static void main(String[] args) {
        //创建线程
        Thread t1 = new subThread();
        //启动线程
        t1.start();
    }
}
class subThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("这是子线程执行的代码:"+i);
        }
    }
}
2)一个定义Runnable接口的实现类
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo02 {
    public static void main(String[] args) {
        //3)定义Runnable接口的实现类对象
        Prime p =new Prime();
        //4)创建线程,调用Thread(Runable)构造方法
        Thread thread = new Thread(p);
        //5)开启新的线程
        thread.start();
    }

}
//1)定义Runnable接口的实现类
class Prime implements Runnable{
    //2)重写接口的run()方法
    @Override
    public void run() {
        for (int i=0;i<100;i++){
            System.out.println("这是子线程执行的程序:"+i);
        }

    }
}
3)其他创建线程的方式
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo03 {
    public static void main(String[] args) {
        //Thread类实现了Runnable接口,SubThread继承了Thread类,SubThread也是Runnable接口的实现类
        subThread thread  =new subThread();
        Thread t3 = new Thread(thread);
        t3.start();

        //
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("这是匿名内部类中的内容:"+i);
                }
            }
        });
        t4.start();

        new subThread().start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("另外一个子线程:"+i);
                }
            }
        }).start();

    }
}
4线程的常用方法

currentThread() 返回当前线程
getName() 返回线程名称
isAlive() 判断线程是否处于活动状态
sleep() 线程休眠
interrupt() 中断线程 只是打了一个中断标志,不是真正的终止线程
yield() 放弃当前线程的cpu执行权 有可能刚放弃就重新获得
getPriority() 线程优先级 1-10 默认优先级是5 一般不做修改
setDaeman 守护线程 守护线程不能独立运行. 典型的守护线程就是垃圾回收线程

currentThread() setName() getName()
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo04 {
    public static void main(String[] args) {
        subThread04 t1 = new subThread04();
        Thread thread = new Thread(t1);
        thread.setName("t1");
        thread.start();
    }
}
class subThread04 implements Runnable{
    public subThread04(){
        System.out.println("构造方法中打印当前线程:"+Thread.currentThread().getName());
    }
    @Override
    public void run() {
        System.out.println("run方法中打印当前线程:"+Thread.currentThread().getName());
    }
}
isAlive()
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo05 {
    public static void main(String[] args) {
        subThread subThread  = new subThread();
        System.out.println("before:"+subThread.isAlive());
        subThread.start();
        System.out.println("after:"+subThread.isAlive());
    }
    //使用静态内部类定义一个Thread线程类的子类,只在当前Demo05类的main方法中使用
    static class subThread extends Thread{
        @Override
        public void run() {
            System.out.println("run ="+this.isAlive());
        }
    }
}
sleep()
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo06 {
    public static void main(String[] args) {
        subThread t1 = new subThread();
        System.out.println(Thread.currentThread().getName()+": before: "+System.currentTimeMillis());
        t1.start();
        System.out.println(Thread.currentThread().getName()+": after: "+System.currentTimeMillis());

    }
    static class subThread extends Thread{
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName()+": before:"+System.currentTimeMillis());
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + ": after:" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
interrupt()

Java中有三种方式可以终止线程的执行:

  1. 使用退出标志,使线程正常退出, 想办法让run()运行结束
  2. 使用stop()强行终止,不建议使用
  3. 使用interrupt()中断线程, 仅仅在是当前线程中打了一个中断标志,并不是真正的终止线程.
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo07 {
    public static void main(String[] args) {

            SubThread t = new SubThread();
            t.start();

            //main线程打印100行
            for (int i = 0; i < 100; i++) {
                System.out.println("main: " + i);
            }
            //中断子线程
            t.interrupt();
            //仅仅是给线程 加一个中断标志, 并没有终止线程
            System.out.println(t.isInterrupted());      //true
        }
        static  class SubThread extends Thread{
            @Override
            public void run() {
                super.run();
                for (int i = 0; i < 1000; i++) {
                    System.out.println("sub thread --> " + i);

                }
            }
        }
}

在子线程中通过判断中断标志来结束线程

package Threadnew;

/**
 * 子线程通过中断标志来退出程序
 * Author:wenyu
 * 2019/9/25
 */
public class Demo08 {
    public static void main(String[] args) {
        subThread t1 = new subThread();
        t1.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
        t1.interrupt();//中断子线程
        System.out.println(t1.isInterrupted());
    }
    static class subThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                if(this.isInterrupted()){
                    System.out.println("当前程序线程被终止");
                   // break;
                    return;
                }
                System.out.println("subThread->"+i);
            }
            System.out.println("这是for循环之后的代码");
        }
    }
}

通过修改标志来结束线程

package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo09 {
    public static void main(String[] args) {
        subThread s1 = new subThread();
        Thread t1 = new Thread(s1);
        t1.start();
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
        //把子线程结束
        s1.running=false;
    }
    static class subThread implements Runnable{
        public boolean running = true; //线程运行标志
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                //检查线程状态
                if (!running){
                    break;
                }
                System.out.println("subThread->"+i);
            }
            System.out.println("这是子线程中for循环之后的代码");
        }
    }
}
getPriority()
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo10 {
    public static void main(String[] args) {
        subThread t1 = new subThread();
        t1.setName("t1");
        //设置线程优先级
        t1.setPriority(1);
        t1.start();
        subThread t2 = new subThread();
        t2.setName("t2");
        //设置线程优先级
        t2.setPriority(10);
        t2.start();
    }
    static class subThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
getDeamon()
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo11 {
    public static void main(String[] args) {
        subThread1 t1 = new subThread1();
        t1.setName("t1");
        t1.setDaemon(true);//将t1设为守护线程
        t1.start();

        subThread2 t2 = new subThread2();
        t2.setName("t2");
        t2.start();
        //当t2线程执行完毕, JVM只有t1线程时,JVM会退出
    }
    static class subThread1 extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    static class subThread2 extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
}
查看线程状态 getState()
ackage Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo12 {
    public static void main(String[] args) throws InterruptedException {
        subThread t1 = new subThread();
        t1.setName("t1");
        System.out.println(t1.getState());//NEW
        t1.start();
        System.out.println(t1.getState());//RUNNABLE
        Thread.sleep(200);
        System.out.println(t1.getState());//TERMINATED
        Thread.sleep(1000);
        System.out.println(t1.getState());//TERMINATED

    }
    static class subThread extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(this.getName()+":"+i);
            }
        }
    }
}
5线程同步

线程同步机制是一种用于协调线程之间数据访问的机制.
Java平台的线程同步机制包括锁, volatile关键字, 相关的方法.Object类中wait()/notify()

1)同步代码块
package Threadnew;

/**
 * Author:wenyu
 * 2019/9/25
 */
public class Demo13 {
    static  int num = 100;        //定义静态变量,作为共享数据
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new subThread().start();
        }
    }
    static class subThread extends Thread{
        static final Object obj = new Object();
        @Override
        public void run() {
            while (true){
            //同步代码块同步实例方法
                synchronized (obj) {
                    while (num>0){
                        System.out.println(Thread.currentThread().getName()+"--"+num--);
                    }
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
				break;
            }
        }
    }
}
2)同步方法

直接使用synchronized修饰方法
如果修饰实例方法就是同步实例方法
如果修饰静态方法,就是同步静态方法

package Threadnew;

/**
 * Author:wenyu
 * 2019/9/26
 */
public class Demo14 {
    public static void main(String[] args) {
        Demo14 obj = new Demo14();
        //开启两个线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo14.print();
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                Demo14.print2();
            }
        }).start();
    }

    public static void print(){
        synchronized (Demo14.class) {//当前类的字节码作为锁对象
            for (int i = 0; i < 50; i++) {
                System.out.println(Thread.currentThread().getName()+":"+i);
            }
        }
    }
    //同步静态方法, 使用当前类的运行时类对象,即类的字节码Test08.class作为锁对象
    public synchronized static void print2(){
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
6.死锁

在多线程中,如果需要获取多个锁对象,如果获取锁对象的顺序不一样,可能造成相互等待的情况,被称为死锁。

7.volatile

volatile关键字的作用就是让变量在多个线程之间可见

package Threadnew;

/**
 * Author:wenyu
 * 2019/9/26
 */
public class Demo15 {
    public static void main(String[] args) throws InterruptedException {
        PrintString obj = new PrintString();
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    obj.printStringMethod();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        //Thread.sleep(100);

        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
        //修改main线程中的continuePrint
        obj.setContinuePrint(false);
    }
    //定义打印字符串的类
    static class PrintString{
        //定义打印标志
        private volatile Boolean continuePrint = true;

        public PrintString setContinuePrint(Boolean continuePrint){
            this.continuePrint=continuePrint;
            return this;
        }

        public void printStringMethod() throws InterruptedException {
            System.out.println("开始打印。。。");
            while (continuePrint){
                for (int i = 0; i < 10000; i++) {
                    if(continuePrint==true){
                        //Thread.sleep(10);
                        System.out.println(i);
                    }else {
                        break;
                    }
                }
            }
            System.out.println("结束打印");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值