Java小练手2 :关于线程开启和关闭

练手题目:

这周抽空做完了老师布置的题目 其中有一道关于线程的题目,还蛮考验人对线程的理解
题目是 开启2个线程,一个打印ABCD…XYZ,一个打印12345…26,要求A1B2C3…Z26依次打印


问题描述:

首先 ,这道题考线程机制的 ,基本烂大街了。 百度一查 答案就有N篇文章,我开始没考虑的问题
导致 结果没有同步输出。
原来代码如下:

package cn.edu.util;

public class Test7 {
    public static void main(String[] args) {
        MyThread1 thread1=new MyThread1();
        thread1.start();
        MyThread2 thread2=new MyThread2();
        thread2.start();

    }
    /**
     * 3、开启2个线程,一个打印ABCD...XYZ,一个打印12345...26,要求A1B2C3....Z26依次打印
     */

}
class MyThread1 extends Thread
{
    @Override
    public void run() {
        String str="12345";
        for(int i=0;i<str.length();i++)
        {
            synchronized (String.class)
            {
                //                    lock.notify();
                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(str.charAt(i)+",");
            }


        }

    }
}
class MyThread2 extends Thread
{
    @Override
     public void run() {
        String str="ABCDE";
        //Object lock=new Object();
        for(int i=0;i<str.length();i++)
        {
            synchronized (String.class)
            {

                try {
                    sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.print(str.charAt(i)+",");

            }

        }

    }
}

没考虑锁之前
后来参考网上2位大佬的代码 进行了修改

大佬1:多线程:Java两个线程,一个打印A-Z,另一个打印1-26,输出结果:A1 B2 C3 … Z26
大佬2:面试题:写两个线程,一个线程打印1~26,另一个线程打印字母A-Z,交替打印数字和字母
但还是出现问题
问题代码1:

package cn.edu.util;

public class Test9 {
    public static void main(String[] args) throws InterruptedException {
        Object lock=new Object();
        Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                String str="ABCDEF";
                for(int i=0;i<str.length();i++)
                {
                    synchronized (lock)
                    {

                        try {
                            System.out.print(str.charAt(i));
                            Thread.sleep(1000);
                            lock.notify();
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(" "+i+"线程1");

                }

                if(Thread.currentThread().isInterrupted())
                {
                    return;
                }
                System.out.println("线程1执行完毕");
            }
        });
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                String str="123456";
                for(int i=0;i<str.length();i++)
                {
                    synchronized (lock)
                    {

                        try {
                            System.out.print(str.charAt(i));
                            Thread.sleep(1000);
                            lock.notify();
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(" "+i+"线程2");

                }

                if(Thread.currentThread().isInterrupted())
                {
                    return;
                }
                System.out.println("线程2执行完毕");
            }
        });
        thread1.start();//打印字符串ABCDEF
        thread2.start();//打印字符串123456

    }
}

问题结果:仔细看 没多大问题 其实眼尖的同学发现问题了 就是**“线程2执行完毕”**这句话并没有打印

出BUG了
并且在IDEA 编译环境下还会出现 线程卡死的情况 即如图片所示 注意红色方块(就是表示程序并没结束 卡死了)
线程卡死
我本来计划是2个线程执行打印完字符串后 ,打印”线程XX执行完毕“结果其中一个不仅没打印出来 而且还出现程序卡死
查了好几篇关于线程中断的文章后,
文章1:Java终止线程的三种方式
文章2:java并发编程— stop() 和 interrupt() 方法的主要区别
尝试用interrupt() 函数 结果还是出问题 虽然抛出了中断异常(正常的运行结果)
测试代码如下
测试代码
抛出异常后 线程还是卡死 程序还是没结束 即小方块还是红色的 注意下面图片中红色小方块
还有”线程2执行完毕“并未打印出来

在这里插入图片描述
在这里插入图片描述


原因分析:

自己问了下老师(项目经理)他说是其中一个线程在另外一个线程打印完字符串执行完毕的时候(最后的时候)并没被唤醒 所以导致异常 而且没必要引入中断函数


解决方案:

在打印字符串(for循环里)的时候加入判断 条件

                for(int i=0;i<str.length();i++)
                {
                    synchronized (lock)
                    {

                        try {
                            System.out.print(str.charAt(i));
                            //Thread.sleep(1000);
                            lock.notify();
                            lock.wait();
                            if(i==str.length()-1)  //引入的判断
                            {
                                lock.notify();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(i+"线程1");

                }

同理 第二个线程里也加如这个判断 这里就不再展示了
具体代码如下

package cn.edu.util;

public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        Object lock=new Object();

        Thread thread1=new Thread(new Runnable() {
            @Override
            public void run() {
                String str="ABCDEF";
                for(int i=0;i<str.length();i++)
                {
                    synchronized (lock)
                    {

                        try {
                            System.out.print(str.charAt(i));
                            //Thread.sleep(1000);
                            lock.notify();
                            lock.wait();
                            if(i==str.length()-1)
                            {
                                lock.notify();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(i+"线程1");

                }
//                if(Thread.currentThread().isInterrupted())
//                {
//                    return;
//                }

                System.out.println("线程1执行完毕");
            }
        });
        Thread thread2=new Thread(new Runnable() {
            @Override
            public void run() {
                String str="123456";
                for(int i=0;i<str.length();i++)
                {
                    synchronized (lock)
                    {

                        try {
                            System.out.print(str.charAt(i));
                            //Thread.sleep(1000);
                            lock.notify();
                            lock.wait();
                            if(i==str.length()-1)
                            {
                                lock.notify();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(i+"线程2");

                }
//                if(Thread.currentThread().isInterrupted())
//                {
//                    return;
//                }
                System.out.println("线程2执行完毕");
            }
        });
        thread1.start();//打印字符串ABCDEF

        thread2.start();//打印字符串123456



    }
}

最后运行结果 “线程1执行完毕” “线程2执行完毕” 均打印出来了
在这里插入图片描述
而且程序正常结束 注意绿色三角就是

修改好后运行正常

最后

暂时先写到这里 ,各位网友如果有更加好的修改方案请留言, 我再试试改改 ,修改好代码 我再对文章进行补充修改 修改好代码
望不吝赐教

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值