Java线程共享数据操作

1.线程共享数据操作

题目1 员工发彩票,从前门和后门入场领取彩票,打印员工
入场入场顺序及领取的彩票信息
import java.util.ArrayList;

public class text {
    public static void main(String[] args) {
        Men run = new Men();//创建线程中转
        Thread t1 = new Thread(run,"前门");//创建线程,并命名
        Thread t2 = new Thread(run,"后门");
        t1.start();//开启线程
        t2.start();
    }
}
class Men implements Runnable{
    private  int pNum = 100;//共享资源100人
    private  int qNum = 0;
    private  int hNum = 0;
    @Override
    public void run() {
        while (true) {
            synchronized(this) {//设置同步锁
                if (pNum <= 0) {//票没了结束运行
                    break;
                }
                //获取线程名字
                String name = Thread.currentThread().getName();//
                //判断入场人数及入场顺序
                if (name.equals("前门")) {
                    System.out.println("编号:" + (100 - pNum + 1)+
                            "从"+name+"入场 号码是:");
                    printcp();
                    pNum--;
                    qNum++;
                }
                if (name.equals("后门")) {
                    System.out.println("编号:" + (100 - pNum + 1)+
                            "从"+name+"入场 号码是:");
                    printcp();
                    pNum--;

                    hNum++;
                }
                if (pNum == 0) {
                    System.out.println("从前门入场" + qNum);

                    System.out.println("从后面入场" + hNum);

                }
            }
            Thread.yield();//让出CPU资源
        }
    }
    //打印彩票信息方法
    public void printcp() {
        //创建ArrayList集合
        ArrayList<Integer> list = new ArrayList<>();
        while (list.size() < 7) {
            //随机产生数字
            int num = (int)(Math.random()* (30-1+1)+1);
            if (!list.contains(num)) {//去重
                list.add(num);//添加数字
            }
        }
        System.out.println(list);//打印结果
    }
}
2.停止线程
1.只要线程停止了就叫停止线程
2.测试interrupt中断线程
public class text {
    public static void main(String[] args) {
         Stop stop = new Stop();//创建线程中转
         Thread thread = new Thread(stop);//创建线程
         thread.start();//开启线程
         thread.interrupt();//中断线程
        System.out.println("线程中断了");
         try {
            Thread.sleep(1000);//睡眠1秒
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 

         System.out.println("主线程结束");
    }
}
class Stop implements Runnable{
    @Override
    public void run() {
        int i = 0;
        while (!Thread.currentThread().isInterrupted()) {//设置死循环
            long start = System.currentTimeMillis();
            while (System.currentTimeMillis() - start < 1000) {//睡眠一秒
            }
            System.out.println(Thread.currentThread().getName() + "-" + i++);

        }

    }

}
测试结果:
1.不能测子线程
2.实际上这个interrupt()方法设置了一个布尔值 isInterrupted
3.如果线程中有waiter()等待 或者sleep睡眠
这时调用interrupt方法就会抛出一个异常 并且清除中断状态
4.如果线程中没有等待或者休眠 这时会调用interrupt方法会设置中断状态(true/false的改变)
5.interrupt方法尽量不要使用,如果停止线程,直接使用标记停止即可
6.只有遇到等待状态时,可以使用该方法,强行清楚该等待状态
2.interrupt 方法的强行解冻
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/*
 * 测试中断状态
 * 注意:interrupt 方法尽量不要使用
 *      如果要停止线程,直接使用标记法停止即可
 *      只有遇到了等待状态时,可以使用该方法
 *      强行清楚该等待状态
 * 
 * 
 * IllegalMonitorStateException
 * 对象监视器就是对象锁 synchronized
 */
public class text {
    public static void main(String[] args) {
        InterruptRunnable interruptRunnable = new InterruptRunnable();
        Thread thread1 = new Thread(interruptRunnable, "线程1");//创建线程
        Thread thread2 = new Thread(interruptRunnable, "线程2");
        thread1.start();//开启线程
        thread2.start();

        for (int i = 0; i < 50; i++) {
            if (i == 25) {
                // 调用中断方法,来清除状态
                thread1.interrupt();
                thread2.interrupt();
                break;
            }
            System.out.println(i + "*-*-*");
        }
        System.out.println("主线程结束");
    }
}
class InterruptRunnable implements Runnable {
    @Override
    public synchronized void run() {
        while (true) {
            try {
                /*
                 * 线程1进来带着锁,遇到 wait 方法
                 * 放弃 CPU 的执行权,锁还回去
                 * 线程2进来带着锁,遇到 wait 方法
                 * 放弃 CPU 的执行权,锁还回去*/

                wait();// 线程等待,放弃了 CPU 的执行资源
            } catch (InterruptedException e) {
                 e.printStackTrace();//捕获中断后wait被强行解冻报出的异常
            }
            Date date = new Date();
            DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
            String format = dateFormat.format(date);
            System.out.println(Thread.currentThread().getName() + format);
        }
    }
}
 1.wait 方法是 Object 类的
 2.注意: wait 方法必须用锁对象去调用
 3.调用 interrupt 方法强行解决清除wait等待状态
 4. 注意: wait 和notify一般成对出现,都是使用锁对象调用
 6.this.notify(); 随机唤醒等待线程中一个
 7.notifyAll() 唤醒所有等待的线程
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值