java中的同步多线程
发布时间:2020-12-15 04:08:19 所属栏目:Java 来源:网络整理
导读:我是自学 Java,我想了解多线程.我创建了MyThread类,其作业执行循环直到条件为真,然后打印有关它的信息.它包含静态字段,它在构造函数中递增,在作业完成时递减.类标志是“告诉”线程何时开始. 不幸的是,当所有线程完成时,left不等于零.我使一些方法同步并且它
我是自学
Java,我想了解多线程.我创建了MyThread类,其作业执行循环直到条件为真,然后打印有关它的信息.它包含静态字段,它在构造函数中递增,在作业完成时递减.类标志是“告诉”线程何时开始.
不幸的是,当所有线程完成时,left不等于零.我使一些方法同步并且它变得更好但它仍然不完美. 我究竟做错了什么? import java.util.Random; class Flag { private boolean ok = false; synchronized boolean ok() { return ok; } synchronized void setOk(boolean ok) { this.ok = ok; } } class MyThread extends Thread { static int left = 0; synchronized void add() { left++; } synchronized int remove() { return --left; } String name; Flag flag; Random rnd = new Random(); public MyThread(String name,Flag flag) { this.name = name; this.flag = flag; add(); } public void run() { while(!flag.ok()); double rnd; long count = 0; do{ count++; rnd = Math.random(); } while(rnd > 0.00001); print(count); } synchronized void print(long count) { System.out.printf("%s %10d left: %3d%n",name,count,remove()); } } public class Test { public static void main(String... args) throws Exception { Flag flag = new Flag(); for(int i=0; i<2000; i++){ new MyThread(String.format("%04d",i),flag).start(); } flag.setOk(true); } } 解决方法
left和–left不是原子操作.当几个线程试图执行时,可能是两个尝试同时向左递减的情况.此行为是由于您的代码在实例级别上同步(print是实例方法),而left是静态(类)变量.
另请注意,print()中打印的值是无序的(因为print不是静态同步的,因此打印的“last”值可能不是调用print的最后一个线程的值). 第一次更改:检查所有线程执行后左边确实为零. public static void main(String... args) throws Exception { java.util.List<Thread> threads = new java.util.LinkedList<Thread>(); Flag flag = new Flag(); for(int i=0; i<20; i++){ Thread thread=new MyThread(String.format("%04d",flag); threads.add(thread); thread.start(); } flag.setOk(true); for (Thread thread:threads) thread.join(); System.out.println(MyThread.left); } 输出: 0003 9527 left: 19 0000 56748 left: 18 0006 11428 left: 17 0016 181845 left: 2 0010 95287 left: 3 0017 137911 left: 4 0018 432172 left: 5 0019 280280 left: 6 0013 421170 left: 7 0012 135830 left: 8 0015 104375 left: 9 0014 207409 left: 10 0001 16157 left: 11 0004 160136 left: 12 0008 31673 left: 13 0002 14589 left: 14 0005 23692 left: 15 0009 83419 left: 16 0011 231135 left: 0 0007 202603 left: 1 0 第二个更改:在类上进行同步(添加,删除和打印转换为静态方法;我们还要在运行中替换调用print,因为静态方法print中的名称不再可见). synchronized static void add() { left++; } synchronized static int remove() { return --left; } synchronized static void print(long count,String name) { System.out.printf("%s %10d left: %3d%n",remove()); } public void run() { ... print(count,name); } 输出: 0012 10207 left: 19 0006 121343 left: 18 0000 16236 left: 17 0008 81429 left: 16 0010 20250 left: 15 0002 14687 left: 14 0015 11051 left: 13 0017 23602 left: 12 0019 19651 left: 11 0005 180155 left: 10 0014 126578 left: 9 0003 41790 left: 8 0016 98362 left: 7 0001 96047 left: 6 0004 334071 left: 5 0009 46827 left: 4 0018 102826 left: 3 0013 71625 left: 2 0007 267208 left: 1 0011 188743 left: 0 0 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |