首页 > 其他分享 >线程问题<1>

线程问题<1>

时间:2023-02-08 11:34:55浏览次数:32  
标签:void 问题 线程 println new public size


实现一个容器,提供两个方法,add,size
写两个线程,线程1添加10个元素到容器中,线程2实现监控元素的个数,当个数到5个时,线程2给出提示并结束


1.第一种方法是使用while一直监听容器的数量变化,个数到达5就退出

缺点: list添加volatile之后,第二个线程能够接到通知,但是,线程的死循环很浪费cpu

public class Test1 {

private volatile List list = new ArrayList();//线程可见
public void add(Object o) {list.add(o);}
public int size() {return list.size();}

public static void main(String[] args) {
final Test1 t = new Test1();
new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
t.add(i);
System.out.println("线程2增加了" + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();

new Thread() {
public void run() {
System.out.println("线程2开始");
while(true) {
if(t.size() == 5) {
System.out.println("线程2退出");
break;
}
}
}
}.start();
}
}



2.第二种方法是使用等待通知机制,这里使用wait和notify做到,wait会释放锁,而notify不会释放锁

第一个线程判断个数不到5就wait 该线程停止执行并释放锁,第二个线程得以执行 把容器个数增加到5就调用notify唤醒线程1,这时候第二个线程要wait释放锁,让第一个线程执行,第一个线程执行结束前,要调用notify唤醒第二个线程,让第二个线程得以继续执行

public class Test2 {
private volatile List list = new ArrayList();
public void add(Object o) {
list.add(o);
}
public int size() {
return list.size();
}
public static void main(String[] args) {
final Test2 t = new Test2();
final Object object = new Object();
new Thread() {
public void run() {
System.out.println("线程2开始");
if(t.size() != 5) {
synchronized (object) {
try {
object.wait();//个数不到5 调用wait()方法,释放锁
object.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
System.out.println("线程2结束");
}
}.start();


new Thread() {
public void run() {
System.out.println("线程1开始");
synchronized (object) {
for (int i = 0; i < 10; i++) {
t.add(i);
System.out.println("线程1添加" + i);
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(t.size() == 5) {
object.notify();
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
System.out.println("线程1结束");
}
}.start();
}

}



3.使用Latch(门闩)替代wait notify来进行通知

好处是通信方式简单,同时也可以指定等待时间

使用await和countdown方法替代wait和notify

CountDownLatch不涉及锁定,当count的值为零时当前线程继续运行
当不涉及同步,只是涉及线程通信的时候,用synchronized + wait/notify就显得太重了
这时应该考虑countdownlatch/cyclicbarrier/semaphore

public class Test3 {

private volatile List list = new ArrayList();

public void add(Object o) {
list.add(o);
}
public int size() {
return list.size();
}
public static void main(String[] args) {

final Test3 t = new Test3();
final CountDownLatch latch = new CountDownLatch(1);//这里是闩上一个门

new Thread() {
public void run() {
System.out.println("线程1启动");
if(t.size() != 5) {
try {
latch.await();//调用该方法,下面的代码停止执行,被闩住了
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("线程1结束");
}
}.start();

new Thread() {
public void run() {
for (int i = 0; i < 10; i++) {
t.add(i);
System.out.println("线程2添加了" + i);
if(t.size() == 4) {
// 打开门闩,让另一个线程得以执行
latch.countDown();
}
}
}
}.start();
}
}




运行的结果

线程1启动
线程2添加了0
线程2添加了1
线程2添加了2
线程2添加了3
线程2添加了4
线程1结束
线程2添加了5
线程2添加了6
线程2添加了7
线程2添加了8
线程2添加了9



标签:void,问题,线程,println,new,public,size
From: https://blog.51cto.com/u_12182769/6043795

相关文章

  • java多线程编程核心技术(1丶2章)
    java多线程编程第一章:实现多线程编程主要有两种方式,一种是继承Thread类,另一种是实现Runnable接口。使用继承Thread类的方式创建新线程时,最大的......
  • javaScript 高级语法 - class创建对象,继承 extends,super,类中this指向问题
    1.class创建对象classHuman{//类constructor(id,name){//构造器this.id=id;//成员变量this.name=name;}info(){//方法console.log("inf......
  • 关于mybatis resulttype 返回值异常的问题
    目录mybatisresulttype返回值异常例如:resulttype="student"但是当中有些字段为空例如:数据库字段为:s_name实体类字段为namemybatisresultType="map"的常见问题一、......
  • Request-获取请求参数中文乱码问题处理、请求转发
    Request获取请求参数中文乱码问题处理中文乱码问题:get方式:tomcat8已经将get方式乱码问题解决了post:会乱码解决:在获取参数前,设置request的......
  • 黑苹果中Memory modules misconfigured问题解决
    问题大致和这个差不多,头一样,下面的不一样:大致意思是,你的内存出现了错误设置,要么成对安装,要么把模块全插满。以前版本没有这个信息,那就一定是配置造成的。按照https://dor......
  • 记一次Java崩溃崩溃问题——IPv6 与 glibc的bug
    最近一段时间,项目组的后端和APP端进行联调的时候,会发现测试服务器的后端服务器会经常莫名其妙地崩溃,最后会生成一份崩溃日志(hs_err_pid.log)。日志的大概信息如下:##Afat......
  • MYSQL因IN的范围太大导致索引失效问题
    背景最近发现有个用于统计的门店串码激活数量的SQL特别慢,将其摘出来大致如下SELECTa.sku_idasskuId,a.store_idasstoreId,count(*)assaleQtyFROMall_imei_inf......
  • Redis(十四)——缓存问题
     1、缓存穿透(1)问题描述缓存和数据库中都没有数据。例如利用不存在的key恶意攻击,导致数据库压力过大(2)解决方案接口层增加参数校验,用户鉴权,id非法拦截。从缓存取......
  • java创建线程的方式有几种?
    java中创建线程的方式有多少种,这个问题也是众多纷纭,这个时候更应该参考官方文档(https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html)了,文档很明确地指出......
  • python 的多线程
    创建一个多线程fromthreadingimportThread,ThreadErrorimporttimedeftask_01():print("开始发送邮件")time.sleep(1)print("邮件发送成功")i......