java线程

线程

线程是操作系统运算调度的最小单位

任务,多线程,进程

进程是一个程序的执行的过程,它是一个动态的概念,是系统资源分配的单位,里面有若干个线程

  • 线程就是独立的执行路径

  • 在程序运行时,即使没有自己创建线程,后台也会有多个线程,如:主线程,gc线程

  • main()称之为主线程,为系统入口,用于执行整个程

Thread class → 继承Thread(重点)

public class TestThread extends Thread{
    @Override
    public void run() {
        System.out.println("54654");
    }
​
    public static void main(String[] args) {
        TestThread testThread=new TestThread();
        //调用start()方法开启多线程,交替执行,同时执行
        testThread.start();
        //先执行run方法在执行后面的输出
        testThread.run();
        System.out.println("78465154");
    }
}

Runnable接口 → 实现Runnable接口(重点)

//创建线程方式2,实现Runable接口,重写run方法,执行线程需要丢入runable接口实现类,调用start方法
public class RunTest3 implements Runnable{
    @Override
    public void run() {
        System.out.println("546");
    }
​
    public static void main(String[] args) {
        RunTest3 runTest3=new RunTest3();
        //创建线程对象,通过线程对象来开启线程,代理
        Thread thread=new Thread(runTest3);
        thread.start();
    }
}
    

抢票问题

package XianChen;
​
public class TestThread4 implements  Runnable{
    private int ticket=10;
    @Override
    public void run() {
        try {
            Thread.sleep(200);//延时2s
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while (ticket!=0){
            System.out.println(Thread.currentThread().getName()+"拿到第"+ticket--+"票");
        }
        System.out.println("票以售空");
    }
​
    public static void main(String[] args) {
        TestThread4 testThread4=new TestThread4();
       new Thread(testThread4,"小明").start();
        new Thread(testThread4,"小红").start();
        new Thread(testThread4,"小光").start();
    }
}
​

龟兔赛跑

​
​
public class TestThread5 implements Runnable {
    private String winner;
​
    public void run() {
        for (int i = 0; i <= 100; i++) {//赛道距离为100
            boolean flag=gameover(i);
            if(flag)
            {
                break;
            }
            System.out.println(Thread.currentThread().getName() + "跑了" + i + "步");
​
        }
​
​
    }
    public boolean gameover(int steps){
        if(winner!=null) {//当胜利者存在时,两个线程的共同参数
            return true;
        }
            else if(steps >= 100) {
                winner = Thread.currentThread().getName();
                System.out.println("胜利者是" + winner);
                return true;
            }
​
​
        return false;
    }
​
​
    public static void main(String[] args) {
        TestThread5 testThread5=new TestThread5();
        new Thread(testThread5,"兔子").start();
        new Thread(testThread5,"乌龟").start();
    }
}
​

Callable接口 → 实现Callable接口(了解)

静态代理

  • 真实对象和代理对象都要实现同一个接口

  • 代理对象要代理真是角色

优点

代理对象可以做很多真实对象做不了的事情

例如: 你:真是对象

婚前公司:代理,帮你处理结婚的事情 相当于 Thread

结婚:两者都是实现结婚这件事,

Lamda表达式

public class lambda {
    public static void main(String[] args) {
 
       //lambda表达式
       Wed wed2=(int a)->{
           System.out.println("68746");
       };
       wed2.ol(7);
        简化后
            Wed  wed2=(a)->System.out.println("68746");
           
    }

优点

  • 避免匿名内部类定义过多

  • 可以让代码看起来更加简洁

  • 去掉了一些没有意义的代码,只留下核心的逻辑

1,函数式接口,一个接口里面只包含一个抽象方法
    public interface Runable{
    void run();
}

线程停止

package XianChen;
//测试Stop
//建议线程正常停止--->利用次数,不建议死循环
//建议使用标志位---->设置一个标志位
//不要使用stop或者destroy等过时或者jdk不建议使用的方法
​
public class StopTest implements Runnable {
    boolean flag=true;
    int i=0;
    @Override
    public void run() {
        while (flag){
            System.out.println("result: "+i++);
​
        }
    }
    public void stop(){
        this.flag=false;
    }
​
    public static void main(String[] args) {
        StopTest stopTest=new StopTest();
        new Thread(stopTest).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main"+i);
            if(i==900){
                stopTest.stop();
                System.out.println("线程该停止了");
            }
        }
    }
}
​

线程休眠sleep

  • sleep(时间)指当前线程阻塞的毫秒数

  • sleep存在异常InterruptException

  • sleep时间达到后线程进入就绪状态

  • sleep可以模拟网络延时,倒计时等

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

package XianChen;
​
import java.sql.DatabaseMetaData;
import java.text.SimpleDateFormat;
import java.util.Date;
​
public class SleepTest  {
    private  int a=10;
    public void sleep() throws InterruptedException{
        while (a>=0){//倒计时
            System.out.println(""+a--);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
​
    public static void main(String[] args) {
        SleepTest sleepTest = new SleepTest();
        Date date=new Date(System.currentTimeMillis());//获取系统时间
        while (true) {
            try {
                Thread.sleep(1000);//延时一秒
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));//输出当前系统时间
                date=new Date(System.currentTimeMillis());//更新当前时间赋值给date
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
​
        }
​
    }
}
​

线程礼让Yield

  • 让当前正在执行的线程暂停,但不阻塞

  • 将线程转换为就绪状态

  • 让cpu重新调度,礼让不一定成功

观察状态

Thread.State  state =Thread.getState();
System.out.pritn(state);

线程的优先级priority

程序先执行优先级高的

public class PriorityTast {
    public static void main(String[] args) {
        System.out.println(Thread.currentThread().getName()+" "+Thread.currentThread().getPriority());//主线程优先级
        priority priority=new priority();
        Thread t1=new Thread(priority);
        Thread t2=new Thread(priority,"2");
        Thread t3=new Thread(priority,"3");
        //先设置优先级,在输出
        t1.start();

        t2.setPriority(4);//设置优先级
        t2.start();

        t3.setPriority(Thread.MAX_PRIORITY);
        t3.start();


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

守护线程

线程分为用户线程和守护线程

虚拟机必须确保用户线程执行完毕

虚拟机不必等待守护线程执行完毕

package XianChen;

public class DaemonTast {
    public static void main(String[] args) {
        people people=new people();
        God god=new God();
        Thread t1=new Thread(god);
        Thread t2=new Thread(people);
        t1.setDaemon(true);//默认为false表示是用户线程,设置为true时为守护线程,正常的线程都为用户线程
        t1.start();//守护线程启动

        t2.start();//用户线程启动
    }
}
class  people implements  Runnable{
    @Override
    public void run() {
        int count=365;
        while (count>=0)
        {
            count--;
            System.out.println("you live happy");
        }
        System.out.println("everthing is over");
    }
}
class God implements Runnable{
    @Override
    public void run() {
         while (true)
         {
             System.out.println("protect you all the time");
         }
    }
}

线程同步

并发:一个对象被多个线程同时执行(列如:抢票)

形成条件:队列+锁(synchronized) 保证线程同步的安全性

存在问题

  • 一个线程持有锁会导致其他所有需要此锁的线程挂起(排队上厕所 锁相当于门)

  • 多个线程竞争下,会导致性能下降

  • 一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能问题

同步方法和同步和代码块

synchronized方法和synchronized代码块
    public synchronized void methon(){
    
}
synchronized(object){//对象为变量
    
}
//银行取钱
public class TicketTast {

    public static void main(String[] args) {
       Account account=new Account(100,"共同资金:");
        bank you=new bank(account,50,"你");
        bank people=new bank(account,100,"朋友");
        you.start();//开启线程
        people.start();
    }
}
   //账户
    class   Account {
        int money;//余额
        String name;//账户名

        public Account(int money, String name) {

            this.money = money;
            this.name = name;
        }
    }
        //银行
    class bank extends Thread {
        Account account;
        int drawingmoney;
        int nowmoney;
        String name;

        public bank(Account account, int drawingmoney, String name) {
            super(name);
            this.account = account;
            this.drawingmoney = drawingmoney;


        }

        @Override
        public void run() {
            synchronized (account) {//synchroized块对账户account进行锁定
                System.out.println(account.name + account.money);
                if (account.money - drawingmoney < 0) {
                    System.out.println(Thread.currentThread().getName() + "的余额不足,取不了");
                    return;
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //银行卡内余额=当前账号余额-取出来的钱
                account.money = account.money - drawingmoney;

                System.out.println(Thread.currentThread().getName() + " 取了钱目前卡内剩下余额:" + account.money);
            }

        }
    }
本身安全的集合
    copyOnwriteArrayList list=new copyOnwriteArrayList();

死锁(隐式)

当某一个同步块同时拥有“两个以上对象的锁时”,就会发生死锁问题

package XianChen;

import Nei.Ma;

public class LockTast {
    public static void main(String[] args) {
        Makeup m1=new Makeup("白雪公主",0);
        Makeup m2=new Makeup("灰姑娘",1);
        new Thread(m1).start();
        new Thread(m2).start();
    }
}
//镜子
class Mirror{

}
//口红
class Lipstick{

}
class Makeup extends Thread{
    String name;//化妆的人
    int choie;

    //需要的资源只有一份,用static类来保证
    static Mirror mirror=new Mirror();
    static Lipstick lipstick=new Lipstick();

    @Override
    public void run() {
        try {
            makeup();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public Makeup(String name,int choie){
        this.name=name;
        this.choie=choie;
    }

    public void makeup() throws InterruptedException {

        if(choie==0){//同时拥有两个锁会导致程序停止运行
            synchronized(mirror){
                System.out.println(this.name+"拿了镜子");//镜子锁
            }
                Thread.sleep(2000);//延时一秒后拿下一个东西
            synchronized(lipstick){
                System.out.println(this.name+"拿了口红");//口红锁
            }
        }//同时拥有两个锁会导致程序停止运行
        else {
            synchronized(lipstick){
                System.out.println(this.name+"拿了口红");
            }
                Thread.sleep(1000);//延时一秒后拿下一个东西
            synchronized(mirror){
                System.out.println(this.name+"拿了镜子");
            }
        }

    }
}

Lock(显示)

  • Lock接口是控制多个线程对共享资源进行访问的工具

  • ReentrantLock类实现了Lock

package XianChen;

import java.util.concurrent.locks.ReentrantLock;

public class LockTast1 {
    public static void main(String[] args) {
        Locktast2 locktast=new Locktast2();
        new Thread(locktast).start();
        new Thread(locktast).start();
        new Thread(locktast).start();
    }
}

class Locktast2 implements Runnable{
    int ticket=10;
    ReentrantLock lock=new ReentrantLock();//设置锁
    @Override
    public void run() {
    try {
        lock.lock();//开锁
        while (true) {

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            if (ticket > 0) {
                System.out.println(ticket--);
            } else {
                break;

            }

        }
    }finally {
        lock.unlock();//关锁
    }
    }

    }

生产者消费者问题

管程法
public class PcTast {
    public static void main(String[] args) {
        Factor factor=new Factor();
        Protect protect=new Protect(factor);
        Consumer consumer=new Consumer(factor);
        protect.start();
        consumer.start();
    }
}
//生产者
class Protect extends  Thread{
    Factor container;
    Protect( Factor container){
        this.container=container;
    }

    @Override
    public void run() {
        for (int i = 1; i < 100; i++) {
            System.out.println("生产了"+i+"只");

            container.push(new duck(i));//将i的值赋值个id
        }
    }
}
//消费者
class  Consumer extends  Thread{
    Factor container;
    Consumer( Factor container){
        this.container=container;
    }

    @Override
    public void run() {
        for (int i = 1; i < 100; i++) {
            System.out.println("消费了"+container.pop().id+"只");

        }
    }
}
//产品
class duck{
    int id;//编号
    public duck(int id){
        this.id=id;
    }
}
class  Factor{
    //容器计数器
    int count=0;
    //容器大小
    duck[] ducks=new duck[10];
    //生产
    public synchronized void push(duck id){
        //容器满了
        if(count==ducks.length){
            //等待消费者消费,生产者等待,
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else {
            //生产商品
            ducks[count]=id;//将i从1-10分别赋值给数组0-10
            count++;
            //生产完毕,通知消费者
            this.notifyAll();
        }
    }
    //消费
    public  synchronized duck pop(){
        //
        if(count==0){
            //等待生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
         //消费者消费
            count--;
            duck id=ducks[count];//dunk为编号id
            //消费玩了,通知生产者
            this.notifyAll();
            return  id;

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值