java学习--线程基础

概念

程序

进程

线程

单线程与多线程

并发与并行

线程基本使用

基成Tread类

关系图


/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class Main {
    public static void main(String[] args) throws InterruptedException {
        Cand cand = new Cand();
        cand.start();
        int i=0;
        while (true){
        System.out.println("主线程启动"+Thread.currentThread().getName());
        i++;
        Thread.sleep(1000);

        if (i==6)
        break;}

    }
}
class Cand extends Thread {
    @Override
    public void run() {

        int time=0;
        while (true) {
            System.out.println("小猫叫");
            time++;

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (time==8)
                break;

        }
    }
}

主线程结束了,子线程没结束那么应用程序就不会结束,除非所有的线程都结束了,应用程序才会结束,并且主线程和子线程会交替进行,不会阻塞,并且使用start方法开始线程他会主动调用run方法,之所以如此原因如下

,并且这样直接调用那么线程就只是main,并且会按照程序进行先进行调用run()方法内的内容,再进行后面的内容

start()启动线程的过程

实现接口Runnable

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class Test01 {
    public static void main(String[] args) {
        Roud roud = new Roud();
        //无法像继承Thread类时可以直接调用start方法启动线程
       // roud.start();
        Thread thread = new Thread(roud);
        thread.start();

    }
}
class Roud implements Runnable {

    @Override
    public void run() {
        int i=0;
        while (true) {


        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("小狗叫了" + Thread.currentThread().getName());
        i++;
        if (i==10)
            break;
    }
}
}

使用这个方式实现调用start方法启动线程是用到了代理模式。我们可以来模拟一下

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class Test02 {
    public static void main(String[] args) {
        Roud_ roud_ = new Roud_();
        PoxyTread poxyTread = new PoxyTread(roud_);
        poxyTread.start();

    }
}

class PoxyTread implements Runnable{
   private Runnable runnable=null;

    public PoxyTread(Runnable runnable) {
        this.runnable = runnable;
    }

    @Override
    public void run() {
        if (runnable!=null)
            runnable.run();
        

    }
    public void start()
    {
        start0();
    }
    public void start0()
    {
        run();
    }

}
class Roud_ implements Runnable {
    @Override
    public void run() {
        int i = 0;
        while (true) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("小狗叫了" + Thread.currentThread().getName());
            i++;
            if (i == 10)
                break;
        }
    }
}
多线程执行

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class Test03 {
    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();
        Thread thread = new Thread(t1);
        Thread thread1 = new Thread(t2);
        thread.start();
        thread1.start();


    }
}
class T1 implements Runnable{

    @Override
    public void run() {
        int i=0;
        while (true)
        {
        System.out.println("mimi"+Thread.currentThread().getName());
        i++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (i==10)
                break;
        }
    }
}
class T2 implements Runnable{

    @Override
    public void run() {
        int i=0;
        while (true)
        {
            System.out.println("mimi"+Thread.currentThread().getName());
            i++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (i==10)
                break;
        }
    }
}

继承Thread与Runnable的区别

线程终止

线程常用方法

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class test05 {
    public static void main(String[] args) throws InterruptedException {
        T_ t = new T_();
        Thread thread = new Thread(t);
        thread.start();

        for(int i=0;i<5;i++)
        {
            Thread.sleep(1000);
            System.out.println("hi"+i);
        }
        thread.interrupt();

    }
}
class T_ implements Runnable{

    @Override
    public void run() {
        while (true)
        {
            for(int i=0;i<100;i++)
            {
                System.out.println("吃包子"+i);
            }
            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName()+"被中断了");
            }
        }
    }
}

如果没有interrupt的话,应该再输出5个hi后再到达睡眠时间sleep(20000)后又开始输出吃包子语句,

有了之后他直接干预了休眠时间,直接就会打印出被干预的话,然后立刻开始又打印吃包子

解析1:

例如当一个cpu在并发运行两个线程时,其中一个使用了yield让CPU先去出里另一个。但是如果CPU他是能同时兼顾这两个的时候,那么yield就不会使用成功

解析2:

例如当一个cpu在并发运行两个线程时,再运行一个线程时,另一个线程使用了join,那么就会先运行完另一个线程的内容,才会再运行这个

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class test06 {
    public static void main(String[] args) throws InterruptedException {
        T_i t = new T_i();
        Thread thread = new Thread(t);
        thread.start();

        for(int i=0;i<20;i++)
        {
            System.out.println("小弟吃包子"+i);
            Thread.sleep(1000);
            if (i==5)
                thread.join();
        }

    }
}
class T_i implements Runnable{

    @Override
    public void run() {
        int i=0; 
        while (true)
        {


                System.out.println("老大吃包子"+(++i));

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            if (i==20)
                break;
        }
    }
}

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
1.主线程每隔1s,输出hi,一共10次
2. 当输出到hi 5时,启动一个子线程(要求
实现Runnable),每隔1s输出hello,等
该线程输出10次 hello后,退出

3.主线程继续输出hi,直到主线程退出.
4.如图,完成代码
*/public class Test07 {
    public static void main(String[] args) throws InterruptedException {
        T_O t_o = new T_O();
        Thread thread = new Thread(t_o);
      // thread.start();
        for(int i=0;i<10;i++)
        {
            System.out.println("hi"+i);
            Thread.sleep(1000);
            if (i==4) {
                thread.start();
                thread.join();
            }


        }
    }
}
class T_O implements Runnable{

    @Override
    public void run() {
        int i=0;
        while (true)
        {
            System.out.println("hello"+(++i));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if (i==10)
                break;

        }
    }
}
用户线程和守护线程

线程的生命周期

7大状态

查看状态方式

线程同步

Synchronized

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class Test04 {
    public static void main(String[] args) {
        sell01 sell01 = new sell01();

        Thread thread = new Thread(sell01);
        Thread thread1 = new Thread(sell01);
        Thread thread2 = new Thread(sell01);
        thread.start();
        thread1.start();
        thread2.start();

    }
}

class sell01  implements Runnable{
    static int tick=100;
    boolean loop=true;
    public synchronized void sell(){
        if (tick<=0)
        {
            System.out.println("票已卖完");
            loop=false;
            return;
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("出售票"+Thread.currentThread().getName()+"剩余"+(--tick));

    }


    @Override
    public void run() {
        while (loop)
        {
            sell();




        }


    }
}


使用完美解决之前卖票不够了还卖的境界

锁在对象上,随机一个线程去拿这个锁打开进入操作相应的操作,然后出来再关闭,然后又随机一个来拿这个锁重复之前的步骤

互斥锁

是因为使用时会都堵塞在这,谁拿到锁谁才能进入执行操作,所以效率低了

注意事项

如果是这样就锁不住了。因为在创建时,都是new了个新对象,那么this指的对象每次都不一样

除了用this也可以用其他对象,只要是三个线程同一的对象就行,比如图上的Object,他是创建在该类的属性,所以三个线程对应的是同一个object对象

死锁

结果就是卡住了死锁

释放锁

import java.util.Scanner;

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
*/public class test08 {
    public static void main(String[] args) {
        C c = new C();
        new Thread(c).start();
        B b = new B(c);
        new Thread(b).start();


    }
}
    class C implements Runnable{
       static boolean loop=true;

        public static void setLoop(boolean loop) {
            C.loop = loop;
        }

        @Override
        public void run() {
           while (loop){

                System.out.println((int)(Math.random()*100+1));
               try {
                   Thread.sleep(10000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }


           }

        }
    }
    class B implements Runnable{
        C a;//想要控制C就得有C对象

        public B(C a) {
            this.a = a;
        }

        Scanner scanner=new Scanner(System.in);

        @Override
        public void run() {
            while (true)
            {
                System.out.println("请输入你的字母");
                char c=scanner.next().toUpperCase().charAt(0);
                System.out.println(c);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {

                }
                if (c=='G')
                {  a.setLoop(false);//改变C控制循环的变量
                    break;
               }




            }

        }
    }

/*
@author:我与java相爱相杀---c语言梦开始的地方
今天又是努力学习的一天!!!!
)有2个用户分别从同一个卡上取钱(总额:10000)
2)每次都取1000,当余额不足时,就不能取款了
3)不能出现超取现象=》线程同步问题.
*/public class Test09 {
    public static void main(String[] args) {
        new Car().run();
        new Car().run();

    }
}
class Car extends Thread{
    static int cash=10000;
    public synchronized void m()
    {
        while (cash!=0)
        {
            cash-=1000;
            System.out.println("还剩"+cash);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值