Java-多线程导学

创建线程

创建方法:

  1. 继承Thread类
  2. 实现Runnable接口
  3. 实现Callable接口
继承Thread类
  1. 继承Thread类
  2. 重写run方法
  3. 调用start方法开启线程
// 创建线程方式一:1.继承Thread类,2.重写run方法,3.调用start方法开启线程
public class ThreadTest extends Thread{
   // 2.
   @Override
   public void run() {
       // run方法线程体
       for (int i = 0; i < 20; i++) {
           System.out.println("run>>>");
       }
   }

   public static void main(String[] args) {

       ThreadTest threadTest = new ThreadTest();
       //3.
       threadTest.start();

       // main线程&主线程
       for (int i = 0; i < 20; i++) {
           System.out.println("main>>>");
       }
   }
}

实现Rannable接口

  1. 实现Rannable接口
  2. 重写run方法
  3. 创建线程对象,执行start方法
	public class RunnableThreadTest implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 200; i++) {
            System.out.println("run>>>");
        }
    }

    public static void main(String[] args) {
        RunnableThreadTest runnableThreadTest = new RunnableThreadTest();
        Thread thread = new Thread(runnableThreadTest);
        thread.start();
        for (int i = 0; i < 200; i++) {
            System.out.println("main>>>");
        }
    }
}

线程停止

// 通过标志位flag停止
public class StopTest implements Runnable{

    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("run>>>"+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>>>");
            if(i==900){
                stopTest.stop();
                System.out.println("线程停止");
            }
        }
    }
}

sleep

yield

join

线程优先级:1-10

守护线程 : daemon

// 守护daemon进程
public class DaemonTest{
    public static void main(String[] args) {
         // 上帝
        God god = new God();
        // 我
        I me = new I();

        Thread thread = new Thread(god);
        thread.setDaemon(true);
        /*
        * 总结: 原本“上帝”进程会进入死循环,而setDaemon(true) > 守护线程
        *       只要用户线程停止,守护线程也随之停止
        * */
        thread.start();

        new Thread(me).start();
    }
}


class I implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("每天都开心,今天是"+i+"天");
        }
        System.out.println("=====Goodbye,world=====");
    }
}

class God implements Runnable{

    @Override
    public void run() {
        while (true){
            System.out.println("上帝守护着我");
        }
    }
}

并发问题

多线程对同一资源同时访问,得到相同的结果;

并发不安全案例


public class UnsafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket = new BuyTicket();
        new Thread(buyTicket, "邓聪").start();
        new Thread(buyTicket,"徐悦祺").start();
        new Thread(buyTicket,"王凡").start();
    }
}


class BuyTicket  implements Runnable{
    // 电影票初始数量
    private int ticketNums = 10;
    boolean flag = true; // 标志位

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

    public void buy() throws InterruptedException {
        //判断是否有票
        if (ticketNums <= 0){
            flag = false;
            return;
        }
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName()+"【购票成功】"+",票号:"+ticketNums--);

    }
}

synchronized

同步方法

public synchronized void buy() throws InterruptedException {
        //判断是否有票
        if (ticketNums <= 0){
            flag = false;
            return;
        }
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName()+"【购票成功】"+",票号:"+ticketNums--);

    }

同步块

@Override
    public void run() {
        // 判断有没有钱
        synchronized (account){
            if(account.money < drawingMoney){
                System.out.println(Thread.currentThread().getName()+"的账户余额不足,请及时充值");
                return;
            }
            // 扣钱
            account.money = account.money - drawingMoney;
            // 得钱
            nowMoney = nowMoney + drawingMoney;

            System.out.println(account.name+"充值成功,余额为"+account.money);

            System.out.println(this.getName()+"余额宝账户余额:"+nowMoney);
        }
    }

死锁

示例:

if (choice == 0){
            synchronized (lipstick){
                System.out.println(this.girl+"获得口红的锁");
                Thread.sleep(1000);
                synchronized (mirror){
                    System.out.println(this.girl+"获得镜子的锁");
                }
            }
        }else {
            synchronized (mirror){
                System.out.println(this.girl+"获得镜子的锁");
                Thread.sleep(2000);
                synchronized (lipstick){
                    System.out.println(this.girl+"获得口红的锁");
                }
            }
        }

Lock 锁

private final ReentrantLock lock = new ReentrantLock();
			try{
                // 加锁
                lock.lock();
                if (ticketNum > 0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"抢票成功,票号:"+ticketNum--);
                }else {
                    break;
                }
            }finally {
                // 解锁
                lock.unlock();
            }

管程法

// 测试生产者消费者模式-利用缓冲区解决:管程法
public class TestPC {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

// 生产者
class Productor extends Thread {
    SynContainer container;
    public Productor(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("生产了第"+i+"只鸡");
        }
    }
}

// 消费者
class Consumer extends Thread {
    SynContainer container;
    public Consumer(SynContainer container){
        this.container = container;
    }

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

// 产品
class Chicken {
    int id;

    public Chicken(int id) {
        this.id = id;
    }
}

// 缓冲区
class SynContainer {

    // 产品
    Chicken[] chickens = new Chicken[10];

    // 容器计数器
    int count = 0;

    public synchronized void push(Chicken chicken) {
        // 如果容器满了,就需要等待消费者消费
        if (count == chickens.length) {
            // 通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 未满,我们需要丢入产品
        chickens[count] = chicken;
        count++;

        // 通知消费者消费
        this.notifyAll();
    }
    // 消费者消费产品
    public synchronized Chicken pop(){
        // 当容器为0,等待生产者生产
        if (count == 0){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        // 消费
        count--;
        Chicken chicken = chickens[count];

        // 通知生产者生产
        this.notifyAll();
        return chicken;
    }

// wait notify count(容器)
}

信号灯法


public class TestPC2 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}

// 生产者:演员
class Player extends Thread {
    TV tv;

    public Player(TV tv){
        this.tv = tv;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0){
                this.tv.play("快乐大本营播放中");
            }else {
                this.tv.play("抖音:记录美好生活");
            }
        }
    }
}

// 消费者:观众
class Watcher extends Thread {

    TV tv;

    public Watcher(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

class TV {
    String voice;
    boolean flag = true;

    // 表演
    public synchronized void play(String voice) {
        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了" + voice);
        // 通知观众看
        this.notifyAll();

        this.voice = voice;

        this.flag = !this.flag;
    }

    // 观看
    public synchronized void watch() {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众看了"+voice);
        // 通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}
// flag wait notify 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值