2020-12-26 Java多线程学习总结


/**
 * 多线程的创建,方式一:继承于thread类
 * 1,创建继承与thread类的子类
 * 2,重写thread类的run()方法-->将此线程执行的操作生命在run()方法中
 * 3,创建thread类的子类的对象
 * 4,通过此对象调用start()方法
 *<p>
 *例子:遍历100以内的所有的偶数
 *
 * @author rieson
 * @create 2020-12-22-9:26
 */
//1创建一个继承与Thread类的子类
class MyThread extends Thread{
    //2重写run()方法
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            if (i %2==0) {
                System.out.println(Thread.currentThread().getName()+""+i);
            }
        }
    }
}
public class ThreadTest {
    public static void main(String[] args) {
        //3创建threadz子类的对象
        MyThread myThread = new MyThread();
        //4通过此对象调用start():1启动当前线程,2调用当前线程的run()
        myThread.start();
        //问题一:我们不能直接调用run()方法
        //问题二:再启动一个线程,遍历100以内的偶数,不可以让已经start()线程再次执行,会报错
        //我们需要重新创建一个线程的对象,让他再次调用start()
        //如下操作仍然实在main线程中执行的
        MyThread myThread1 = new MyThread();
        myThread1.start();
        for (int i = 0; i < 100; i++) {
            if (i %2==0) {
                System.out.println(i+"*");
            }
        }
    }

}




/**
 * 测试Thread类中的方法:
 * 1,start():启动当前线程,调用当前线程的run()
 * 2,run():通常需要重写Tread的类中的此方法,将要执行的操作定义在此方法中
 * 3,currentThread:静态方法,返回执行当前代码的线程
 * 4,getName():获取当前线程的名称
 * 5,setName():设置当前线程的名称
 * 6,yield():释放当前线程执行权
 * 7,join():线程a中调用线程b中join方法时,a线程就会进入阻塞状态,直到b线程执行完毕后再结束阻塞状态
 * 8,stop():强制结束当前线程,已过时,不建议使用
 * 9,sleep(long milltime):线程睡眠指定的毫秒数,
 * 10,idAlive():判断当前线程是否还存活
 *
 *
 *
 * 线程的优先级:
 * 1,略
 *
 * 2,如何获取和设置线程的优先级
 *      getPriority():获取线程的优先级
 *      setPriority(int p):设置线程的优先级
 *
 *
 *
 * @author rieson
 * @create 2020-12-22-10:46
 */
class MyTreadmethod extends Thread {
    @Override
    public void run() {

        for (int i = 0 ; i < 100; i++) {
            if (i % 2 == 0) {
//                try {
//                   // sleep(1000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                System.out.println(Thread.currentThread().getName()+Thread.currentThread().getPriority()+":" + "" + i);
            }
            if (i % 20 == 0) {
                yield();
            }
        }
    }

    public MyTreadmethod(String name) {
        super(name);
    }
}

public class ThreadMethodTest {
    public static void main(String[] args) {
        MyTreadmethod myTreadmethod = new MyTreadmethod("Thread: 1");
        // myTreadmethod.setName("线程一");
        myTreadmethod.start();
        myTreadmethod.setPriority(Thread.MAX_PRIORITY);
        //主线程命名
        Thread.currentThread().setName("主线程");
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {

                System.out.println(Thread.currentThread().getName() + "" + i);
            }
//            if (i ==20) {
//                try {
//                    myTreadmethod.join();
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//            }
        }
    }
}



/**
 * 创建多线程的方法二:
 * 1,创建一个实现Runnable()接口的类
 * 2,实现类去实现Runnable中的抽象方法
 * 3,创建实现类的对象
 * 4,将此对象作为参数传递到Thread类的构造器中,创建Thread的对象
 * 5,通过Thread类的对象来调用start()方法
 *
 * @author rieson
 * @create 2020-12-22-12:38
 */
//1,创建一个实现Runnable()接口的类
class RunNable implements Runnable{
//    int s;
//    public RunNable(int s){
//        this.s=s;
//    }
    @Override
    public void run() {

            for (int i = 0; i < 100; i++) {
                if (i % 2 == 0) {
                    System.out.println(i);
                }
            }
    }
}
public class ThreadTest1 {
    public static void main(String[] args) {
        //3,创建实现类的对象
        RunNable runNable = new RunNable();
        //4,将此对象作为参数传递到Thread类的构造器中,创建Thread的对象
      new  Thread(runNable).start();
        new Thread(runNable).start();

    }

}




/**
 *例子:创建三个窗口卖票,总票数为100张,使用实现Ruunable接口的方式
 * 1,创建一个实现Runnable接口类
 * 2,实现类实现run()方法
 * 3,创建实现类对象
 * 4,将此对象作为参数传递到Thread类构造器中,创建Thread类的对象
 * 5,调用Thread类中的start()方法
 *
 * 比较创建线程的两种方法
 * 开发中优先选择Ruunable接口的方法:
 * 1,实现的方式没有类的单继承得局限性
 * 2,实现方式更适合处理多个线程有共享数据的情况
 * 联系:thread也继承了Runnable方法
 * 相同的点都是重写run(),将要执行的逻辑代码都是放在run()中
 * @author rieson
 * @create 2020-12-22-13:13
 */

class Window1 implements Runnable{

    private int stick =100;
    @Override
    public void run() {
        while (true){
            if (stick>0) {
                System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
                stick--;
            }else{
                break;
            }

        }


    }
}
public class WindowTest1 {
    public static void main(String[] args) {
        Window1 window1 = new Window1();

       Thread t1= new Thread(window1);
        t1.start();
        t1.setName("窗口一:");
        Thread t2= new Thread(window1);
        t2.start();
        t2.setName("窗口二:");
        Thread t3= new Thread(window1);
        t3.start();
        t3.setName("窗口三:");




    }

}




/**
 *例子:创建三个窗口卖票,总票数为100张,使用实现Ruunable接口的方式
 * 1,创建一个实现Runnable接口类
 * 2,实现类实现run()方法
 * 3,创建实现类对象
 * 4,将此对象作为参数传递到Thread类构造器中,创建Thread类的对象
 * 5,调用Thread类中的start()方法
 * 比较创建线程的两种方法
 * 开发中优先选择Ruunable接口的方法:
 * 1,实现的方式没有类的单继承得局限性
 * 2,实现方式更适合处理多个线程有共享数据的情况
 * 联系:thread也继承了Runnable方法
 * 相同的点都是重写run(),将要执行的逻辑代码都是放在run()中
 *
 *
 *
 * -------------------------------------------------------
 * 1,问题:买票过程中出现了重票和,错票的 所谓的线程安全问题
 * 2,出现的原因,阻塞状态时,多个线程同时操作到同一个票
 * 3,如何解决:等第一个线程操作共享数据时,其他线程不能参与进来,直到此线程操作完成时,其他线程才能操作
 *             即使是阻塞状态时,也是如此
 * 4,在JAVA中,通过同步机制,来解决线程安全问题
 *     方式一:同步代码块
 *     synchronized(同步监视器){
 *         //需要被同步的代码
 *
 *     }
 *     说明:操作共享数据的代码 = 需要被同步的代码 --->不能包含多了,也不能包含少了
 *          共享数据 = 多个线程共同操作的数据
 *          同步监视器 = 锁:任何一个对象都可以充当锁
 *          要求:多个线程必须共用同一把锁
 *          说明:在继承Tread类,创建多线程的方式,我们可以考虑使用this充当同步监视器
 *
 *     方式二:同步方法
 *           给共享代码块,写在一个方法中,用synchrnoized 定义此方法。
 *     方式三:同步锁
 *      eg:1,面试题:synchronized 与同步锁的异同?
 *               同:都可以解决线程安全问题
 *              不同:synchronized 机制再执行玩同步代码后,自动释放同步监视器
 *              lock需要手动的释放调用(unlock)
 *          2,如何解决线程安全问题?有哪几种方式?
 *          答:同步代码块,同步方法,同步锁
 *5,同步的方式:解决掉了线程安全的问题----好处
 *  操作代码时,只能由一个线程操作,其他线程等待,相当于是一个单线程,效率低
 *
 *
 *
 *
 *
 *
 * @author rieson
 * @create 2020-12-22-13:13
 */

class Window1 implements Runnable{

    String z = "asd";
    private int stick =100;
    //1,实例化
    private ReentrantLock lock=new ReentrantLock();
    @Override
    public void run() {
        while (true){
            try {
            lock.lock();
            if (stick>0) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
                stick--;
            }else{
                break;
            }
        }finally{
            lock.unlock();
        }
        }
    }
    }
    //方式一
//    @Override
//    public void run() {
//        while (true){
//            //用当前对象去充当
//            synchronized (this){
//            if (stick>0) {
//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
//                System.out.println(Thread.currentThread().getName() + "卖了多少票号:" + stick);
//                stick--;
//            }else{
//                break;
//            }
//            }
//        }
//
//
//    }
//}

class Test{

}
public class WindowTest1 {

    public static void main(String[] args) {
        Window1 window1 = new Window1();

       Thread t1= new Thread(window1);
        t1.start();
        t1.setName("窗口一:");
        Thread t2= new Thread(window1);
        t2.start();
        t2.setName("窗口二:");
        Thread t3= new Thread(window1);
        t3.start();
        t3.setName("窗口三:");




    }

}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值