java 中Thread

作者: Exception_Cui | 来源:发表于2021-05-11 16:31 被阅读0次

    首先了解下线程的状态


    微信图片_20210513144401.png

    继承方式实现

    package ThreadTest;
    
    /**
     * Created by kumamon on 2021/5/13.
     */
    public class ThreadDemo {
        public static void main(String[] args) {
            MythreadDemo mythreadDemo = new MythreadDemo();
            mythreadDemo.start();
        }
    
    }
    class MythreadDemo extends Thread{
        @Override
        public void run() {
            System.out.println("使用 extends Thread 来创建线程");
        }
    }
    
    

    Ruannable方式(推荐使用,因为java是单继承,这种方式还可以有父类)

    package ThreadTest;
    
    /**
     *  Runnable
     * 直接使用 extends  Thread 的方式 不能实现多继承
     * 使用这种方式可以继续继承其他的类
     * 解耦
     *
     * Created by kumamon on 2021/5/12.
     */
    public class Runnable {
        public static  void main(String[] args) {
            Thread thread=new Thread(new MyRunnableMain());
            thread.start();
        }
    
    
    }
    class MyRunnableMain implements java.lang.Runnable {
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName()+ i);
            }
        }
    }
    

    线程守护

    package ThreadTest;
    
    /**
     * 守护线程
     * 一个线程设置为守护线程后,当被守护的线程退出了,那么自己的线程也就退出
     *
     * main里面只能创建一个唯一的线程,要么守护线程不起效
     * Created by kumamon on 2021/5/13.
     */
    public class Thread_Deamon {
        public static void main(String[] args) throws InterruptedException {
            T1 t1 = new T1();
            t1.setDaemon(true); //T1 设置为main的守护线程 ,当main线程结束后,T1也跟着结束
            t1.start();
    
            //T2 t2 = new T2();
            //t2.start();  // T2没有设置,main 线程结束后,T2还在执行,等T2结束后,进程停止
    
            for (int i = 0; i < 5; i++) {
                Thread.sleep(1000);
                System.out.println("主线程   正在执行");
            }
            System.out.println("主线程执行完毕,退出");
        }
    
    }
    
    
    
    class T1 extends Thread {
        @Override
        public void run() {
            for (;;) {  //死循环
                try {
    
                    Thread.sleep(1000);
                    System.out.println("子线程 1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
    class T2 extends Thread {
        @Override
        public void run() {
            for (;;) {  //死循环
                try {
    
                    Thread.sleep(1000);
                    System.out.println("子线程 2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    线程加入和让出

    package ThreadTest;
    
    /**
     * Created by kumamon on 2021/5/13.
     */
    public class Thread_Join_Yield {
        public static void main(String[] args) {
            Thread thread=new T();
            thread.start();
    
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+"正在吃"+i+"包子");
                    if(i==5){
                        /**
                         * 线程加入。
                         * 主线程在执行过程中, 让 子线程先执行
                         *
    
                         @System.out.println("子线程加入先吃包子");
                         @thread.join(); 
    
                         * */
    
                        /**
                         * 线程礼让。(是执行自己礼让)
                         * 主线程在执行过程中, 让子线程先执行
                         * 这种方式不一定成功,取决于电脑的CPU调度
                         @System.out.println("自己礼让,让子线程先吃");
                         @Thread.yield();
                         * */
    
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class T extends  Thread{
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                try {
                    Thread.sleep(1000);
                    System.out.println(this.getName()+"正在吃"+i+"包子");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    不同步的线程(数据不合理)

    package ThreadTest;
    
    /**
     * 窗口同时在卖一张票, 还卖了不存的票,(数据不合理)
     * 相当于 3个人在同一时间上同一个厕所
     * <p>
     * Created by kumamon on 2021/5/12.
     */
    public class Thread_No_Synchronized {
        public static void main(String[] args) {
            MyRunnable1 myRunnable = new MyRunnable1();
    
            Thread thread1 = new Thread(myRunnable, "窗口1");
            Thread thread2 = new Thread(myRunnable, "窗口2");
            Thread thread3 = new Thread(myRunnable, "窗口3");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    
    }
    
    class MyRunnable1 implements java.lang.Runnable {
        int sum = 100;
    
        @Override
        public void run() {
            while (true) {
                if (sum > 0) {  //判断票数还有多少张呢
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
                    sum--;
                }
            }
        }
    }
    

    同步代码块(数据合理) 还是上面的例子,不会出现-1 张票

    package ThreadTest;
    
    /**
     * 使用 Synchronized  前提是多个线程 访问同一个数据 (线程安全)
     * 相当于 3个人在同一时间上同一个厕所
     * 但是只能一个一个来,一个上完另一个在上
     * <p>
     *
     *
     *  原理就是 jvm在运行时会检测这个锁的对象属于那个线程
     *  这样争抢的过程中,只能有锁对象的执行
     *
     *
     * Synchronized 包含的是 访问同一数据的代码
     *
     * Created by kumamon on 2021/5/12.
     */
    public class Thread_Synchronized_Object {
    
        public static void main(String[] args) {
            MyRunnable4 myRunnable = new MyRunnable4();
    
            Thread thread1 = new Thread(myRunnable, "窗口1");
            Thread thread2 = new Thread(myRunnable, "窗口2");
            Thread thread3 = new Thread(myRunnable, "窗口3");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    
    
    }
    
    class MyRunnable4 implements java.lang.Runnable {
        int sum = 100;  //票数
        Object obj = new Object();  //设置锁 对象为Object 可以为任意的
        @Override
        public void run() {
            synchronized (obj) {
                while (sum > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
                    sum--;
                }
            }
        }
    
    }
    

    同步方法(数据安全)

    package ThreadTest;
    
    /**
     * 使用同步方法(数据安全)
     * 和
    
     * 相当于 3个人在同一时间上同一个厕所
     * 但是只能一个一个来,一个上完另一个在上
     * <p>
     * Created by kumamon on 2021/5/12.
     */
    public class Thread_Synchronized_Method {
        public static void main(String[] args) {
            MyRunnable2 myRunnable = new MyRunnable2();
    
            Thread thread1 = new Thread(myRunnable, "窗口1");
            Thread thread2 = new Thread(myRunnable, "窗口2");
            Thread thread3 = new Thread(myRunnable, "窗口3");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    
    
    
    }
    class MyRunnable2 implements java.lang.Runnable {
        int sum = 100;  //票数
    
        Object obj = new Object();  //设置锁 对象为Object 可以为任意的
    
        @Override
        public void run() {
            pay();
    
            /**
             * 等同于如下代码  不过obj 是 MyRunnable  而已就是this
            synchronized (obj) {
             while (sum > 0) {
    
             try {
             Thread.sleep(10);
             } catch (InterruptedException e) {
             e.printStackTrace();
             }
             System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
             sum--;
             }
             }
             */
    
        }
    
        private synchronized void pay(){
            while (sum > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
                sum--;
            }
        }
    
    
    }
    

    静态同步方法

    package ThreadTest;
    
    /**
     * 使用 Synchronized  前提是多个线程 访问同一个数据 (线程安全)
     * 相当于 3个人在同一时间上同一个厕所
     * 但是只能一个一个来,一个上完另一个在上
     *
     * 这种一般来保证 单例模式  的线程安全
     *
     *
     * <p>
     * Created by kumamon on 2021/5/12.
     */
    public class Thread_Synchronized_Method_Static {
    
        public static void main(String[] args) {
            MyRunnable3 myRunnable = new MyRunnable3();
    
            Thread thread1 = new Thread(myRunnable, "窗口1");
            Thread thread2 = new Thread(myRunnable, "窗口2");
            Thread thread3 = new Thread(myRunnable, "窗口3");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    
    
    }
    class MyRunnable3 implements java.lang.Runnable {
        static int sum = 100;  //票数
        @Override
        public void run() {
            payStatic();
        }
    
        private static synchronized void payStatic(){  //此处的锁是 MyRunnable3 .class  不是this对象
            while (sum > 0) {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
                sum--;
            }
        }
    
    }
    

    Lock锁同步

    package ThreadTest;
    
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 使用 Lock  前提是多个线程 访问同一个数据 (线程安全)
     * 相当于 3个人在同一时间上同一个厕所
     * 但是只能一个一个来,一个上完另一个在上
     * <p>
     * <p>
     *
     * 使用方式
     *
     *  创建Lock 对象
     *  Lock lock = new ReentrantLock();
     *
     *  在访问共享数据前
     *
     *  lock.lock();
     *  ***
     *  *访问共享数据代码
     *  ***
     *  lock.unlock();
     *
     *  建议增加try 这样无论这次操作是否有异常 都会释放,让下一个线程访问
     *
     * Created by kumamon on 2021/5/12.
     *
     *
     */
    public class Thread_Lock {
    
        public static void main(String[] args) {
            MyRunnable myRunnable = new MyRunnable();
    
            Thread thread1 = new Thread(myRunnable, "窗口1");
            Thread thread2 = new Thread(myRunnable, "窗口2");
            Thread thread3 = new Thread(myRunnable, "窗口3");
            thread1.start();
            thread2.start();
            thread3.start();
        }
    
    
    
    }
    class MyRunnable implements java.lang.Runnable {
        int sum = 100;  //票数
    
        Lock lock = new ReentrantLock();
    
    
        @Override
        public void run() {
            lock.lock();
            try {
                while (sum > 0) {
    
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "正在卖" + sum + "张票");
                    sum--;
                }
            } finally {
                lock.unlock();
            }
        }
    }
    
    

    线程死锁

    • 线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,
    • 由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,
    • 在该线程释放这个锁之前,其它线程是获取不到这个锁的,
    • 而且会一直死等下去,因此这便造成了死锁。
    package ThreadTest;
    
    /**
     *
     * 线程死锁是指两个或两个以上的线程互相持有对方所需要的资源,
     * 由于synchronized的特性,一个线程持有一个资源,或者说获得一个锁,
     * 在该线程释放这个锁之前,其它线程是获取不到这个锁的,
     * 而且会一直死等下去,因此这便造成了死锁。
     *
     *
     * Created by kumamon on 2021/5/13.
     */
    public class ThreadDead {
        public static void main(String[] args) {
            MyThreadDead threadA = new MyThreadDead(true);
            MyThreadDead threadB = new MyThreadDead(false);
    
            threadA.start();
            threadB.start();
        }
    }
    
    class MyThreadDead extends Thread{
    
        boolean flag=true;
        public static Object o1= new Object();
    
        public static Object o2 =new Object();
    
        public MyThreadDead(boolean flag) {
            this.flag = flag;
        }
    
        @Override
        public void run() {
            if(flag){
                synchronized (o1){
                    System.out.println("A线程持有了 o1的对象锁,未执行完 不释放 o1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (o2){
                        System.out.println("A线程");
                    }
    
                }
            }else{
                synchronized (o2){
                    System.out.println("B线程持有了 o2的对象锁,未执行完 不释放 02");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (o1){
                        System.out.println("B线程");
                    }
    
                }
            }
    
    
        }
    }
    
    

    线程通讯

    package ThreadTest;
    
    /**
     * Created by kumamon on 2021/6/3.
     * <p>
     * 模拟
     * 观众看电视
     * 演员录电视
     */
    public class Thread_TongXun {
    
        public static void main(String[] args) {
            TV tv = new TV();
            new Yanyuan(tv).start();
            new Guanzhong(tv).start();
        }
    }
    
    class Yanyuan extends Thread {
        TV tv;
    
        public Yanyuan(TV tv) {
            this.tv = tv;
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                tv.yan();
            }
    
        }
    }
    
    class Guanzhong extends Thread {
        TV tv;
    
        public Guanzhong(TV tv) {
            this.tv = tv;
        }
    
    
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                tv.kan();
            }
    
        }
    }
    
    
    class TV {
    
     
        boolean flag = false;  //设置标志位,什么时候演员录  什么时候观众看
    
        public synchronized void yan() {
    
            //等待观众看完的通知
            if (flag) {  //演员录
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("演员录完电视,通知观众看电视");
            this.flag = !this.flag;
            this.notifyAll();//通知观众
    
    
    
        }
    
        public synchronized void kan() {
            if (!flag) {   //观众看
                //等待 演员录完电视的通知
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("观众看完了电视-----通知演员继续录");
             this.flag = !this.flag;
            this.notifyAll();
         
    
    
        }
    
    }
    
    
    image.png

    相关文章

      网友评论

        本文标题:java 中Thread

        本文链接:https://www.haomeiwen.com/subject/bxcndltx.html