线程之旅 (一Thread)

什么是进程什么是线程

进程:1 进程表示的是资源统一分配,任务调度,一般是程序调用
线程:进程包含线程,进程里可以有多个线程

线程的启动

第一种线程 currentThread

找到正在执行的线程 currentThread

  public static void main(String[] args){
        System.out.println(Thread.currentThread().getName());
    }

代码运行结果与代码的执行顺序无关

/**
 * @Author: judy
 * @Description: run 方法是main方法调用和start方法是线程调用的 ,run表示的同步进行, start表示异步进行
 * @Date: Created in 8:59 2019/2/22
 */
public class CurrentThreadDemo extends Thread {
    @Override
    public void run() {
        super.run();
        System.out.println("this is run="+currentThread().getName());
    }
    public CurrentThreadDemo(){
        System.out.println("this is 构造方法="+currentThread().getName());
    }
    public static void main(String[] args){
        CurrentThreadDemo currentThreadDemo = new CurrentThreadDemo();
        currentThreadDemo.start();
    }
}

start 的 作用,start在代码中的位置与执行结果不一致

public class myThreadDemo extends Thread {
    @Override
    public void run() {
        super.run();
        System.out.println("this is first demo");
    }
    public static void main(String[] args){
        myThreadDemo myThreadDemo =new myThreadDemo();
        myThreadDemo.start();
        System.out.println("maybe should end");

    }
}


maybe should end
this is first demo

为什么会有runable

由于java是单继承,所以当我们适应extends继承Thread的时候发现自己已经继承了其他类,所以这个可以使用runable,实现效果是一样的,并且Thread构造方法可以参数可以是ruable

如何使用

/**
 * @Author: judy
 * @Description: run运行,展示Thread的构造函数可以使用runable, 以及为什么使用runnable ,
 * @Date: Created in 23:39 2019/2/21
 */
public class myRunnableOneDemo implements Runnable {
    @Override
    public void run() {
        System.out.println("运行中");
    }
    public static void main(String[] args){
        Runnable runnable= new myRunnableOneDemo();
        Thread thread = new Thread(runnable);
        thread.start();
        System.out.println("运行结束");
    }
}

什么线程安全

线程安全指的是多个线程一起运行的时候变量的值最终是正确的,不会多也不会少.

下面代码是线程安全的,因为他们线程之间没有共享变量,所以数据是安全的

/**
 * @Author: judy
 * @Description: 不共享变量(数据的情况)
 *
 * @Date: Created in 7:55 2019/2/22
 */
public class VariableSecurityDemo extends  Thread{
    private int count =5;

    public VariableSecurityDemo(String name){
        super();
        this.setName(name);
    }

    @Override
    public void run() {
        super.run();
        while (count>0){
            count--;
            System.out.println("由"+this.currentThread().getName()+"计算count is value"+count);
        }
    }

    public static void main(String[] args){
        //每个线程自己有一个count,不共享,所以数据都是安全的
        VariableSecurityDemo variableSecurityDemo1= new VariableSecurityDemo("A");
        VariableSecurityDemo variableSecurityDemo2= new VariableSecurityDemo("B");
        VariableSecurityDemo variableSecurityDemo3= new VariableSecurityDemo("C");
        VariableSecurityDemo variableSecurityDemo4= new VariableSecurityDemo("D");
        variableSecurityDemo1.start();
        variableSecurityDemo2.start();
        variableSecurityDemo3.start();
        variableSecurityDemo4.start();
    }
}

什么是线程不安全

线程不安全指的是大家对同一个变量进行修改操作,最终到导致结果不一致,不正确

/**
 * @Author: judy
 * @Description: 共享数据
 * @Date: Created in 8:03 2019/2/22
 */
public class ShareDataDemo extends Thread {

    private int count = 6;

    /**
     * 1 取得原有i值;
     * 2 计算i-1;
     * 3 对i 进行赋值;
     * 多个线程对统一对象中的同一个实例变量进行操作
     */
    @Override
     public void run() {
        super.run();
        count--;
        System.out.println(this.currentThread().getName()+"计算count is="+count);
    }
    public static void main(String[] args){
       ShareDataDemo shareDataDemo = new ShareDataDemo();
       Thread thread1= new Thread(shareDataDemo,"1");
       Thread thread2= new Thread(shareDataDemo,"2");
       Thread thread3= new Thread(shareDataDemo,"3");
       Thread thread4= new Thread(shareDataDemo,"4");
       Thread thread5= new Thread(shareDataDemo,"5");
       Thread thread6= new Thread(shareDataDemo,"6");
       thread1.start();
       thread2.start();
       thread3.start();
       thread4.start();
       thread5.start();
       thread6.start();
    }

}

如何变成线程安全

变线程安全有很很多种做法,目前介绍的是synchronized , 为什么加sync就会线程安全,其实就是实现同步效果,一个一个的运行, 这样就不会出现两个线程同时操作一个变量,导致最终结果不正确.

@Override
     synchronized public void run() {
        super.run();
        count--;
        System.out.println(this.currentThread().getName()+"计算count is="+count);
    }

如何看线程当前的状态

使用 isAlive( )

/**
* @Author: judy
* @Description: isAlive 表示线程处于什么状态
* @Date: Created in 9:18 2019/2/22
*/
public class MyThread extends Thread {
   @Override
   public void run() {
       //线程处于什么状态
       System.out.println("run="+this.isAlive());
   }
}

class run{
   public static void main(String[] args) throws InterruptedException {
       MyThread myThread = new MyThread();
       System.out.println("begin=="+myThread.isAlive());
       myThread.start();
       Thread.sleep(1000);
       System.out.println("end=="+myThread.isAlive());
   }
}

查看当前线程是否中断

查看线程终端总共有两种方式
1 使用isInterrupted()
2使用interrupt()

public class MyThread extends Thread {
    @Override
    public void run() {
        super.run();
        for (int i = 0; i <50000 ; i++) {
            System.out.println("i="+(i+1));
        }
    }

    public static void main(String[] args) throws InterruptedException {
//        MyThread myThread = new MyThread();
//        //start异步
//        myThread.start();
//        Thread.sleep(5000);
//        //interrupt表示中断
//        Thread.currentThread().interrupt();

        Thread thread = new Thread();
        thread.start();
        Thread.sleep(5000);
        thread.interrupt();
        System.out.println("查看当前线程是否中断-1-"+thread.isInterrupted());
        System.out.println("查看当前线程是否中断-2-"+thread.isInterrupted());
        System.out.println("end");
    }

为什么会出现两次false

使用 Thread.currentThread().interrupt(); 进行中断

为什么第一次是false第二次是true

interrupt 具有清理作用,会把第一次的状态清理,所以第二次的时候就是false

线程贡献cpu交给其他线程执行 yield

两次运行的时间是不一致,所以最终效果不一样

/**

 * @Author: judy
 * @Description: yield biaoshi
 * @Date: Created in 10:50 2019/2/22
 */
public class YieldDemo extends Thread {
    @Override
    public void run() {
        long timeStart = System.currentTimeMillis();
        int count =0;
        for (int i = 0; i < 500000; i++) {
            // 测试使用yield和不使用的时间差
           // Thread.yield();
            count=count+(i+1);
        }
        long timeEnd= System.currentTimeMillis();
        System.out.println("总共用时="+ (timeEnd-timeStart));
        super.run();
    }
    public static void main(String[] args){
     YieldDemo yieldDemo = new YieldDemo();
     yieldDemo.start();
    }
}

守护线程代码

/**
 * @Author: judy
 * @Description: 守护线程
 * @Date: Created in 11:06 2019/2/22
 */
public class DaemonDemo extends Thread {
    private int count = 0;

    @Override
    public void run() {
        super.run();
        while (true){
            count++;
            System.out.println("count="+(count));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Run{
    public static void main(String[] args) throws InterruptedException {
        DaemonDemo daemonDemo = new DaemonDemo();
        daemonDemo.setDaemon(true);
        daemonDemo.start();
        Thread.sleep(1000);
        System.out.println("end");
    }


 }
内容概要:《学术研究提示设计 50 招》是一份详尽的指南,旨在帮助研究人员提高学术写作和研究效率。该文档涵盖了从论文撰写、润色、翻译、查重降重、参考文献管理、投稿审稿到文献阅读等多个方面的具体操作指令。每一章节均针对特定任务提供了详细的步骤和注意事项,例如如何撰写标题、摘要、致谢,如何进行英文润色、中英翻译,以及如何优化逻辑结构等。文档还介绍了如何利用AI工具进行文献分析、术语表提取和研究方向探索等内容,为研究者提供了全面的支持。 适合人群:适用于学术研究人员,特别是那些需要撰写、润色和提交学术论文的研究者,包括研究生、博士生及高校教师等。 使用场景及目标:① 提供一系列具体的指令,帮助研究者高效完成论文的各个部分,如撰写标题、摘要、致谢等;② 提供润色和翻译的详细指导,确保论文语言的准确性和专业性;③ 提供查重降重的方法,确保论文的原创性;④ 提供参考文献管理和投稿审稿的指导,帮助研究者顺利发表论文;⑤ 利用AI工具进行文献分析、术语表提取和研究方向探索,提高研究效率。 阅读建议:此资源不仅提供了具体的指令和方法,更重要的是引导研究者如何思考和解决问题。因此,在学习过程中,不仅要关注具体的步骤,还要理解背后的原理和逻辑,结合实际案例进行实践和反思。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王雪芬-ghqr-264962

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值