java多线程编程

Little BigUs 2021-05-01 05:55:03

下面是代码,我想问的是循环中的sleep语句注释与不注释会产生什么影响,我之所以会有这个疑问是因为书上说多个线程访问同一资源时会有线程安全问题,例如下面的代码就可能出现第0张票甚至第-1张票的可能,但是我发现下面的代码如果没有sleep就几乎不会出现差错,而加上sleep后几乎次次都会差错,我一直认为出现差错就是在while(tickets > 0)这一句的判断上,如果a线程和b线程同时运行,此时tickets=1,当a判断时显然结果是true,但是当a还没执行到tickets--这一步时b又进行判断的,得到的结果也是true,所以会出现0的情况,当然由于线程执行速度很快,所以差错只是偶尔出现,但如果人为的sleep就会提高差错率,可是如果按照我的想法的话,把sleep放到tickets--后面的话就不会影响了,因为此时的tickets已经变了,但事实证明不像我想的那样,求指教

这应该和 tickets-- 或 --tickets没什么关系吧,我都试过了

package ThreadTest;

public class Example05 {

public static void main(String[] args) {
TicketWindow2 tw = new TicketWindow2();
Thread t1 = new Thread(tw, "窗口一");
Thread t2 = new Thread(tw, "窗口二");
Thread t3 = new Thread(tw, "窗口三");
t1.start();
t2.start();
t3.start();
}
}

class TicketWindow2 implements Runnable {

int tickets = 10;
@Override
public void run() {
// TODO Auto-generated method stub
while(tickets > 0) {
System.out.print(Thread.currentThread().getName()+"正在出售第"+tickets-- +"张票!\n");
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }

}
}

}
...全文
336 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_1113502097 2021-05-06
  • 打赏
  • 举报
回复
简单的解释就是,假如商店在卖东西,然后你和小伙伴一起进去买,如果不排队(也就是多线程),你和你的小伙伴同时问,可乐还有吗,这时候店员回答你,可乐还有(实际上只剩一个了,但有一个也是有),而你和小伙伴都想要这个可乐,谁都不想让,于是打起来了,就不安全了。
=PNZ=BeijingL 2021-05-06
  • 打赏
  • 举报
回复


Java内存模型规定所有的变量都是存在主存当中,每个线程都有自己的工作内存。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存, 执行线程必须先在自己的工作线程中对变量i所在的缓存行进行赋值操作,然后再写入主存当中。而不是直接将数值写入主存当中

当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值
qybao 2021-05-03
  • 打赏
  • 举报
回复
去学习一下同步的知识点吧 没有同步控制,不管你的sleep在前在后,结果都是不确定的。因为线程的执行本身就是随机的,也就是说cpu什么时候切换线程执行,你是控制不了的,你怎么就能这么自信cpu一定是在运行sleep之后才切换线程的?
宾灬 2021-05-03
  • 打赏
  • 举报
回复
sleep 会导致线程阻塞,线程加入阻塞队列,时间到了会被唤醒,加入到就绪队列,都sleep 10ms,很有可能下次唤醒时有两个或三个线程被同时唤醒,同时执行就会出现同一张票被两个线程同时卖,你可以改成Thread.sleep(new Random().nextInt(10)); 让每个线程sleep不同的时间,就不容出现并发问题。不加sleep也有线程安全问题,只是并发量太小,不容易出现。要测并发问题,可以用CyclicBarrier让线程同时执行。 另外: tickets-- 操作也不具有原子性;int tickets = 10 不具有线程可见性,可以加个volatile.

62,635

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧