java线程与锁

一.新建一个线程

方式1:继承Thread

//新建线程继承Thread
public class newthread extends Thread{
    //重写父类中的run方法
    @Override
    public void run() {//run中写自己的业务逻辑
        System.out.println("测试线程1");
        //让该线程休眠一秒
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
//调用
public class testThread {
    public static void main(String[] args) {
        //测试newthread;
        newthread newthread = new newthread();
        newthread.start();
         //newthread.run();错误:start首先启动线程最终会执行线程中的run()方法,如果只是调用run不用start就是简单调用一个方法,并不是真正启动一个线程,而是把run执行完毕才向下执行
    }
}

注意事项:一个进程的主线程结束,但是还有其他线程在运行时,并不会结束这个程序,会执行完剩下的程序

方式二:实现Runnable接口

原因:java是单继承的在某些情况下,一个类可能已经继承了某个父类,这时再用继承Thread类来城建线程无法实现

代码实现:

//新建线程类实现Runnable接口
public class Run implements Runnable{
    int count=0;
    @Override
    public void run() {
        while(true){
            System.out.println("第二种方法创建线程"+(++count)+Thread.currentThread().getName());
            //休眠1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(count==10){
                break;
            }
        }
    }
    
    
    
    //调用方法
    public class runTest {
    public static void main(String[] args) {
        Thread thread = new Thread(new Run());
        thread.start();
    }
}
    

注意:上述两种方法是没有本质区别的都是调用Runnable中的start方法中的start0; 注意:上述两种方法是没有本质区别的都是调用Runnable中的start方法中的start0;

二.Runnable的方法实现多线程

代码实现:

public class Thread3 {
    public static void main(String[] args) {
        test1 test1 = new test1();
        test2 test2 = new test2();
        Thread thread = new Thread(test1);
        Thread thread1 = new Thread(test2);
        thread.start();
        thread1.start();

    }
}
class test1 implements Runnable{
int count1=0;
    @Override
    public void run() {

        while (true) {
            //每隔一秒输出hello
            System.out.println("hello"+(count1++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(count1==10){
                break;
            }
        }
    }
}
class test2 implements Runnable{

    @Override
    public void run() {
        int count2 = 0;
        while (true) {
            //每隔一秒输出hello
            System.out.println("world"+(count2++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            if(count2==10){
                break;
            }
        }
    }
    }

三.线程的常用方法

1.setName,设置线程名称

2.getName返回该线程的名称

3.start使该线程开始执行,java虚拟机底层调用该线程的start0方法

4.run调用线程对象的run方法

5.setPriority更该线程的优先级

6.getPriority获取线程的优先级

7.sleep在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

8.interrupt 中断线程

9.yield线程的礼让,让出cpu让其他线程执行,但礼让时间不确定,所以不一定礼让成功

10.join线程插队,插队的线程一旦插队成功一定会优先执行完插入的程序的所有任务

四.用户线程与守护线程

1.用户线程:也叫工作线程

2.守护线程:一般是为了工作线程服务的,当所有的用户线程结束守护线程自动结束

3.常见的守护线程:垃圾回收机制

守护线程举例:

public class sh {
    public static void main(String[] args) throws InterruptedException {
        shxc shxc = new shxc();
        shxc.setDaemon(true);//将子线程设置为守护线程,注意先设置后start,此时主线程结束后子线程会自动结束
        shxc.start();
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程在工作");
            Thread.sleep(1000);
        }
    }
}
class shxc extends  Thread{
    public void run(){
        for (; ;){//死循环
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("守护线程");
        }
    }
}

五.解决线程安全问题

卖票案例:

1.自动锁:synchronized,自动上锁和释放锁,同一时刻只让一个线程执行2.手动锁ReentrantLock,需要手动上锁解锁

2.手动锁ReentrantLock,需要手动上锁解锁

//自动锁
public class suo {
    public static void main(String[] args) {
        sell sell = new sell();

        Thread thread = new Thread(sell);
        Thread thread1 = new Thread(sell);
        thread.start();
        thread1.start();


    }
}
class sell implements Runnable{
    private int ticket=100;

    @Override
    public void run() {
        while(true){
            synchronized (this){
                if (ticket>0){
                    ticket--;
                    System.out.println(Thread.currentThread().getName()+"剩余票数"+ticket);
                }else {
                    break;
                }
            }
        }
    }
}

//手动锁
public class Soudongsuo {
    public static void main(String[] args) {
        sds sds = new sds();
        Thread thread = new Thread(sds);
        Thread thread1 = new Thread(sds);
        thread1.start();
        thread.start();
    }
}
class sds implements Runnable{
    private int ticket=100;
    private Lock l=new ReentrantLock();//手动创建一个锁

    @Override
    public void run() {
        while(true){
            l.lock();
            if(ticket>0){
                ticket--;
                System.out.println(Thread.currentThread().getName()+"剩余票数"+ticket);
            }else{
                break;
            }
            l.unlock();

        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值