回炉重造java----多线程

概念

883e32949e1443fc9a70ccac0fd670d3.jpg

注: main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集(gc )线程

线程的创建

74d09aa44b0943abaae52fe7ad8d4364.jpg

第一种:继承Thread类,重写run方法(其底层也是实现了Ruunable接口)

20fd67ff441e4316b6dac3aea432234e.jpg

faed3d395f61438784314047dcbdcf81.jpg

第二种:实现Runnable接口,重写run方法(启动线程时要把对象丢进Thread对象中)

56bd891d2612485eb6b75d528515cab9.jpg

d2cf1ecc79bd473f99dfcd1ef64ad70d.jpg


两种方式的总结:

实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类

第三种:实现Callable接口(了解)

bcc9a4a6960d4f419b02cfe07919aac5.jpg

线程属性

 ①线程ID,标识线程

 ②线程名字    ③线程优先级(1-10),优先级越高越优先执行,但并不成正比关系

④线程状态,NEW   RUNNALBE  BLOCKED  WAITING  TERMINATED

⑤线程类别,ture标识守护线程(后台记录操作日志,监控内存,垃圾回收),false标识用户线程。虚拟机必须保证用户线程的执行完毕,不用等待守护线程执行

线程状态

b8be8c213f2f487d9afba094b5aa163e.jpg

线程休眠sleep():

①参数为阻塞线程的毫秒数

②阻塞时间到了之后线程进入就绪状态

③每个对象都有一把锁,sleep不会释放锁

等待线程停止join():

①相当于插队,在主线程中是子线程join(),即主线程等待子线程执行完毕再执行

线程礼让yield():

①礼让的意思是停止cpu对该进程的执行,即从运行状态变成就绪状态

②礼让不一定成功,得看cpu的调度

线程停止:

①使其自动运行完然后停止

②可以设置一个标志位flag来停止线程

③不要使用stop()和destory()等过时或者JDK不建议的方法去停止线程

线程同步(并发)

package Algorithm.SYN;

public class UnsafeThread {

    public static void main(String[] args) {
        Buytciket buytciket = new Buytciket();

        new Thread(buytciket,"1号").start();
        new Thread(buytciket,"2号").start();
        new Thread(buytciket,"3号").start();
    }

}


class Buytciket implements Runnable{

    //定义总数量
    private int TicketNum = 10;
    boolean flag = true;

    @Override
    public void run() {
        //买票
        while (flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }
    
    private void buy() throws InterruptedException {
        //判断是否有票
        if(TicketNum <= 0){
            flag = false;
            return;
        }
        //模拟延时
        Thread.sleep(100);
        //买票
        System.out.println(Thread.currentThread().getName()+"买到了第"+TicketNum--+"票");
    }
}

可见出现了线程的并发问题。

 锁机制(synchronized):

synchronized锁又可以分为synchronized方法和synchronized块:其默认锁的是this,即对象本身。synchronized块锁的是变化的量(对象)。

    //synchronized同步方法
    private synchronized void buy() throws InterruptedException {
        //判断是否有票
        if(TicketNum <= 0){
            flag = false;
            return;
        }

        //买票
        System.out.println(Thread.currentThread().getName()+"买到了第"+TicketNum--+"票");
    }

 拓展:JUC包下的安全集合CopyOnWriteArrayList,可以实现线程集合安全

 

死锁

 private void mu() throws InterruptedException {
        if(choice == 0){
            //获得口红
            synchronized (lipstick){
                System.out.println(this.name+"获得口红");
                Thread.sleep(1000);

                synchronized (m){
                    System.out.println(this.name+"获得镜子");
                }
            }
        }
        else{
            //获得口红
            synchronized (m){
                System.out.println(this.name+"获得镜子");
                Thread.sleep(2000);

                synchronized (lipstick){
                    System.out.println(this.name+"获得口红");
                }
            }
        }

发生死锁!!进程全部阻塞 

private void mu() throws InterruptedException {
        if(choice == 0){
            //获得口红
            synchronized (lipstick){
                System.out.println(this.name+"获得口红");
                Thread.sleep(1000);
            }

            synchronized (m){
                System.out.println(this.name+"获得镜子");
            }
        }
        else{
            //获得口红
            synchronized (m){
                System.out.println(this.name+"获得镜子");
                Thread.sleep(2000);
            }

            synchronized (lipstick){
                System.out.println(this.name+"获得口红");
            }
        }

产生死锁的条件:

 

 Lock锁(显式)

 两种锁的对比:

 

 

 线程池

public class pool {

    public static void main(String[] args) {

        //创建线程池
        ExecutorService service = Executors.newFixedThreadPool(10);//线程池大小

        //执行
        service.execute(new my());
        service.execute(new my());
        service.execute(new my());
        service.execute(new my());

        //关闭连接
        service.shutdown();
    }
}

class my implements Runnable{
    
    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
    }
}

  • 25
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值