Java-线程

57 阅读2分钟

线程Thread

​ 【一个进程里面包含多个线程,线程就是程序运行的最小单位】

CPU的工作方式:多核多线程

一.创建线程的方式

1.方式一:

创建一个新的执行线程有两种方法。 一个是将一个类声明为Thread的子类。 这个子类应该重写Thread里面的run方法。

例如:

public class LolThread extends Thread{
    
    @Override
    public void run() {
    //覆写一百次runn方法
        for (int i = 0; i < 100; i++) {
            System.out.println("aaaaaaaaaaaaa");
        }
    }
}

public class ThreadTest {

	//其中有三个线程 main lolThread.start() 
    public static void main(String[] args) {
        LolThread lolThread = new LolThread();
        MusicThread musicThread = new MusicThread();
        //开启一个独立线程,等待被cpu选中,选中以后自己回去调用对象里面的run方法
        lolThread.start(); //只是开启一个线程,不会立刻去运行里面的任务逻辑
        musicThread.start();



        System.out.println("------------------------------------");
        System.out.println("------------------------------------");
        System.out.println("------------------------------------");
        System.out.println("------------------------------------");


    }
}

2.方式二:

创建一个类 实现Runnabl接口 覆写run方法

创建一个实现类对象作为参数的传入Thread对象里面,并调用start方法

例如:

public class BoThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("正在播放电影");
        }
    }
}


public class ThreadTest {
    public static void main(String[] args) {
      

        KuaiBoThread kuaiBoThread = new KuaiBoThread();
        Thread thread = new Thread(kuaiBoThread);
        thread.start();


        System.out.println("------------------------------------");
        System.out.println("------------------------------------");
        System.out.println("------------------------------------");
        System.out.println("------------------------------------");


    }
}

3.相关面试题:

3.1这两种创建线程的方式哪种好

​ 答:一般来说是实现 Java中是单继承多实现

3.2启动线程的时候:调用run和start有什么区别?

​ 答:调用run不是去开启线程去运行,仅仅只是简单的对象调用方法

买票案例:

继承---------------------------------------

public class TicketThread extends Thread{

    private static int num = 50;
    TicketThread(){}
    TicketThread(String name){
        super(name);
    }

    @Override
    public  void run() {
        while (num>0){
            sale();
        }
    }

    public synchronized void sale(){
        if (num>0) {
            System.out.println(super.getName()+"购买票为:"+num);
            num--;
        }

    }
}




public class TicketTest {
    public static void main(String[] args) {
        TicketThread t1 = new TicketThread("12306");
        TicketThread t2 = new TicketThread("携程");
        TicketThread t3 = new TicketThread("飞猪");

        t1.start();
        t2.start();
        t3.start();
    }
}

实现--------------------------------

public class TicketThread implements Runnable{

    private static int num = 50;


    @Override
    public  void run() {
        while (num>0){
            sale();
        }
    }

    public synchronized void sale(){
        if (num>0) {
            System.out.println(Thread.currentThread().getName()+"购买票为:"+num);
            num--;
        }

    }
}


public class TicketTest {
    public static void main(String[] args) {
        TicketThread t = new TicketThread();

        new Thread(t,"12306").start();
        new Thread(t,"携程").start();
        new Thread(t,"飞猪").start();
    }
}

二.线程安全:

​ 在代码执行的过程中,有一些不正常的情况,所以会实行线程切换

解决线程安全:

1.同步代码块:

​ synchronized(同步对象){

​ 会发生线程问题的代码

​ }

​ 同步对象:

​ 可以写同步的资源

例如:

继承


public class TicketThread extends Thread{

    private static int num = 50;
    TicketThread(){}
    TicketThread(String name){
        super(name);
    }

    @Override
    public  void run() {
        while (num>0){
            sale();
        }
    }

    public synchronized void sale(){
        if (num>0) {
            System.out.println(super.getName()+"购买票为:"+num);
            num--;
        }

    }
}

测试

public class TicketTest {
    public static void main(String[] args) {
        TicketThread t1 = new TicketThread("12306");
        TicketThread t2 = new TicketThread("携程");
        TicketThread t3 = new TicketThread("飞猪");

        t1.start();
        t2.start();
        t3.start();
    }
}

2.同步方法:

​ 在方法的修饰符后面添加synchronized

​ 步方法解决线程安全问题

例如:

继承


public class TicketThread extends Thread{

    private static int num = 50;
    TicketThread(){}
    TicketThread(String name){
        super(name);
    }

    @Override
    public  void run() {
        while (num>0){
            sale();
        }
    }

    public synchronized void sale(){
        if (num>0) {
            System.out.println(super.getName()+"购买票为:"+num);
            num--;
        }

    }
}
测试

public class TicketTest {
    public static void main(String[] args) {
        TicketThread t1 = new TicketThread("12306");
        TicketThread t2 = new TicketThread("携程");
        TicketThread t3 = new TicketThread("飞猪");

        t1.start();
        t2.start();
        t3.start();
    }
}

3.Lock锁

Lock上锁

unLock 释放锁

例如:

实现
public class TicketThread extends Thread{

    private static int num = 5000;
    private static ReentrantLock reentrantLock = new ReentrantLock();
    TicketThread(){}
    TicketThread(String name){
        super(name);
    }

    @Override
    public void run() {
        //新建一把锁

        while (num>0){
            reentrantLock.lock();//上锁

            if (num>0) {
                System.out.println(super.getName()+"购买票为:"+num);
                num--;
            }
            reentrantLock.unlock();//释放锁
        }

    }
}

测试

public class TicketTest {
    public static void main(String[] args) {
        TicketThread t1 = new TicketThread("12306");
        TicketThread t2 = new TicketThread("携程");
        TicketThread t3 = new TicketThread("飞猪");

        t1.start();
        t2.start();
        t3.start();
    }
}