java基础之线程

线程的基本概念

一个程序中可以有多条同时执行的线索,一个线程就是程序中执行的一条线索,每个线程都关联有需要执行的代码,即程序可以同时执行多段代码块,每个程序至少有一个线程,就是main方法执行的主线程。
如果是单核的cpu如何同时执行多段程序呢?
其实cpu是一会执行a线索,一会执行b线索,切换的时间非常短,所以给人感觉是a,b线索同时执行

线程的状态:
就绪、运行、阻塞、挂起、结束
调用线程的start方法后,线程进入就绪状态,线程调度系统会将就绪状态转变为运行状态。
当遇到synchronized语句时,线程会进入阻塞状态,当获得锁后,会从阻塞状态变为运行状态。
当线程在synchronized阻塞时,可以调用wait方法,使其变为挂起状态
直接调用sleep方法也会进入挂起状态(wait与sleep的区别:https://blog.youkuaiyun.com/weixin_43864073/article/details/87826427
线程中的代码执行完之后就变为结束状态

线程同步与异步:
如果数据在线程中共享,如一个线程正在写的数据可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,就需要使用线程同步存取。
当应用程序在对象上调用了一个需要很长时间执行的方法,并且程序并不需要得到这个方法的返回值
,此时应该采用异步编程,也就是使用多线程

实现线程的三种方法:

1.继承Thread类
public class MyThread extends Thread {
@Override
public void run() {
System.out.println(“MyThread”);
}

public static void main(String [] args){
    MyThread myThread =new MyThread();
    myThread.start();

}

}

2.实现Runnable接口
public class MyThread implements Runnable {

@Override
public void run() {
    System.out.println("MyThread");
}

public static void main(String [] args){
    Thread thread=new Thread(new MyThread());
    thread.start();
}

}

3.使用线程池
public class MyThread {

public static void main(String [] args){
ExecutorService pool=Executors.newFixedThreadPool(1);
pool.execute(new Runnable() {
@Override
public void run() {
System.out.println(“MyThread”);
}
});
pool.shutdown();
}
}

synchronized与Lock的异同

相同点:
synchronized能做的事Lock都能做。。。
不同点:
Lock具有更好的性能及更精确的线程语义,synchronized会自动释放锁,Lock则要求程序员手动释放锁,并且必须在finally语句中释放

附带一个线程题

子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。

先实现一轮的子线程循环10次,接着主线程循环100

public class ThreadTest {
//这个用于判断哪个线程该执行
    private static boolean isShouldMain = false;

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 10; i++) {
//用字节码对象当锁,因为它是唯一的
                    synchronized (ThreadTest.class) {
//先判断是否是主线程执行,是的话,把子线程挂起
                        if(isShouldMain){
                            try {
                                ThreadTest.class.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
//当循环次数到10次时,把isShouldMain赋值为true,并唤醒主线程
                        if(i==10){
                            isShouldMain=true;
                            ThreadTest.class.notify();
                        }
                        System.out.println("子线程:" + i);
                    }
                }

            }
        }).start();
        for (int i = 1; i <= 100; i++) {
            synchronized (ThreadTest.class) {
                if(!isShouldMain){
                    try {
                        ThreadTest.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
//当循环次数到100次时,把isShouldMain赋值为false,并唤醒子线程
                if(i==100){
                    isShouldMain=false;
                    ThreadTest.class.notify();
                }
                System.out.println("主线程:" + i);
            }
        }
    }
}

50次循环的版本,道理是一样的,只是重复50次

public class ThreadTest {
    private static boolean isShouldMain = false;

    public static void main(String[] args) {

        new Thread(new Runnable() {
            @Override
            public void run() {
//加了50次循环
                for (int j=1;j<=50;j++){
                    for (int i = 1; i <= 10; i++) {
                        synchronized (ThreadTest.class) {
                            if(isShouldMain){
                                try {
                                    ThreadTest.class.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                            if(i==10){
                                isShouldMain=true;
                                ThreadTest.class.notify();
                            }
                            System.out.println("循环次数:"+j+",子线程:" + i);
                        }
                    }
                }
            }
        }).start();
        for (int j=1;j<=50;j++){
            for (int i = 1; i <= 100; i++) {
                synchronized (ThreadTest.class) {
                    if(!isShouldMain){
                        try {
                            ThreadTest.class.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    if(i==100){
                        isShouldMain=false;
                        ThreadTest.class.notify();
                    }
                    System.out.println("循环次数:"+j+",主线程:" + i);
                }
            }
        }

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值