java的多线程

线程的概念等之前讲过,今天主要写线程的安全性问题

1.实现多线程的两种方式:

package com.zs.service;

/**
 * 通过继承实现多线程,
 * 优点:代码简单
 * 缺点: 单继承的局限性
 */
public class Demo1 extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "第" + i + "次");
        }
    }

    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        Demo1 demo2 = new Demo1();
        demo1.start();
        demo2.start();
    }
}
package com.zs.service;

/**
 * 实现继承的第二种方式,通过实现runnable接口实现多线程
 * 优点:避免了单继承的局限行
 * 缺点:代码比较复杂
 *
 * 通常使用这种方式实现多线程,代码的可拓展性更强
 */
public class Demo2 implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + "第" + i + "次");
        }
    }

    public static void main(String[] args) {
        Demo2 demo2 = new Demo2();
        Thread t1 = new Thread(demo2);
        Thread t2 = new Thread(demo2);
        t1.start();
        t2.start();
    }
}

多线程主要有以上两种实现方式,一般使用接口的方式实现多线程,因为代码的拓展性强,下面我们来通过一个案例来理解线程的同步锁:

模拟一个网络买车票,多个窗口一块卖同一批车票,因此是多线程,下面通过代码实现:

package com.zs.service;

public class ChePiao implements Runnable {
    private int count=50;//定义总共有50张票
    private int num = 0;//卖出第几张票
    @Override
    public void run() {
        while (true) {
            if (count <= 0) {
                break;
            }
            count--;
            num++;
            /*模拟网络延迟*/
            if (count == 10) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"卖出第"+num+"张票");
        }
    }

    public static void main(String[] args) {
        ChePiao chePiao = new ChePiao();
        Thread t1 = new Thread(chePiao, "窗口1");
        Thread t2 = new Thread(chePiao, "窗口2");
        Thread t3 = new Thread(chePiao, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

运行结果:

会出现这种情况,这是不正确的,因为同一张票只能出售一次,因此就需要引入同步机制

package com.zs.service;

public class ChePiao implements Runnable {
    private int count=50;//定义总共有50张票
    private int num = 0;//卖出第几张票
    @Override
    public void run() {

        while (true) {
            /**
             * synchronized 同步锁,将可能产生数据安全的代码锁起来,这样被锁起来的代码就会编程单线程
             * 两种解决同步安全问题:
             * 1.同步代码块
             * 2.同步方法  public synchronized void fun(){..}在返回值前加同步锁
             */
            synchronized (this) {
                if (count <= 0) {
                    break;
                }
                count--;
                num++;
                System.out.println(Thread.currentThread().getName()+"卖出第"+num+"张票");
            }
            /*模拟网络延迟*/
            if (count == 10) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    public static void main(String[] args) {
        ChePiao chePiao = new ChePiao();
        Thread t1 = new Thread(chePiao, "窗口1");
        Thread t2 = new Thread(chePiao, "窗口2");
        Thread t3 = new Thread(chePiao, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}
原文地址:https://www.cnblogs.com/Zs-book1/p/11123057.html