我正在努力学习同步。根据我所了解的,下面的代码应该给出8000作为最终结果,但是我得到了一个随机的结果,如下所示;
import java.time.LocalDateTime;
public class A implements Runnable {
String name;
static Integer j=0;
A(String name){
this.name=name;
}
@Override
public synchronized void run() {
for(int i=1;i<=1000;i++){
synchronized(this){
A.j++;
}
}
System.out.println(j);
}
package threads;
public class MainClass {
public static void main(String args[]){
Thread t1=new Thread(new A("i am thread A "));
Thread t2=new Thread(new A("i am thread B "));
Thread t3=new Thread(new A("i am thread C "));
Thread t4=new Thread(new A("i am thread D "));
Thread t5=new Thread(new A("i am thread E "));
Thread t6=new Thread(new A("i am thread F "));
Thread t7=new Thread(new A("i am thread G "));
Thread t8=new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
还是得到1293 2214 1403 3214 4214 5214 6224 7037这样的输出有没有人能给我解释一下如何实现同步,这里出了什么问题?
代码中有几个问题。
> < li>
问题1:在< code>synchronized(..)不在所有线程实例之间共享
第2期:< code > system . out . println(j);行应该在< code>t8.join()之后结束;否则,您将获得8倍的输出。
修正代码
public class A implements Runnable {
String name;
static Integer j = 0;
static Object lockObject = new Object();
A(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lockObject) {
A.j++;
}
}
}
public static void main(String args[]) {
Thread t1 = new Thread(new A("i am thread A "));
Thread t2 = new Thread(new A("i am thread B "));
Thread t3 = new Thread(new A("i am thread C "));
Thread t4 = new Thread(new A("i am thread D "));
Thread t5 = new Thread(new A("i am thread E "));
Thread t6 = new Thread(new A("i am thread F "));
Thread t7 = new Thread(new A("i am thread G "));
Thread t8 = new Thread(new A("i am thread H "));
t1.setPriority(Thread.MAX_PRIORITY);
t8.setPriority(Thread.MIN_PRIORITY);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
t8.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
t6.join();
t7.join();
t8.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(A.j);
}
}
这将解决问题。您必须使用共享锁对所有线程进行< code>synchronize,因为您正在递增一个静态字段。否则,每个对象将拥有自己的锁,并并行递增静态字段,从而导致竞争情况。这就是为什么你没有得到正确的值,在这个例子中是8000。
package bookmarks;
public class A implements Runnable {
String name;
static Integer j = 0;
private static Object lock = new Object();
A(String name) {
this.name = name;
}
@Override
public void run() {
for (int i = 1; i <= 1000; i++) {
synchronized (lock) {
A.j++;
}
}
System.out.println(j);
}
}
认为synchronized
表示“关键部分”,并且在同步块运行时不会运行其他线程,这是一个常见的错误。但是,同步块只对锁定在同一锁上的其他同步块具有独占性。
你得到的答案(“使用普通锁”)是对的,但没有真正告诉你为什么。另一个常见的错误是认为< code>synchronized是保护代码,而实际上你应该考虑它保护数据。任何共享的可变数据都应该由一个锁来保护,并且只有一个锁,你应该确切地知道那个锁是什么。(您的锁定方案越复杂,您就越不可能知道什么锁保护什么数据。)因此,您应该始终考虑“数据X由锁L保护”,然后确保无论何时访问(读或写)该数据时都获得锁L。
问题内容: 我正在尝试运行以下内容。 如果我删除以下行: 至.... 一切都会正常。如果没有,我得到以下错误: 命令不同步; 您现在不能运行此命令 在研究,我认为这可能是由于多个库MySQLi查询同时运行,其中使用但在所有样品和通用数据导向似乎并不适用。 有任何想法吗? 问题答案: MySQL客户端不允许您执行新的查询,在该查询中仍需要从正在进行的查询中获取行。有关常见错误,请参见MySQL文档中
我正在使用python 2.7。win8上的9。当我尝试使用matplotlib绘图时,出现以下错误: 从pylab导入* 绘图([1,2,3,4]) [matplotlib.lines.Line2D对象位于0x0392A9D0] 我尝试了测试代码“python simple_plot.py--verbose help”,出现了以下警告: $HOME=C:\Users\XX matplotlib数
给定一个0和1的数组,我们最多可以将K个值从0更改为1。 返回仅包含1的最长(连续)子数组的长度。 例1: 例2: 注: https://leetcode.com/problems/max-consecutive-ones-iii/ 这是问题链接。在第一个测试用例中,我得到了输出9,但应该是6。我不知道哪里出了问题?
问题内容: 我已经开始学习线程同步。 同步方法: 同步块: 什么时候应该使用方法和块? 为什么块比方法更好? 问题答案: 这不是更好的问题,只是有所不同。 同步方法时,实际上是在与对象本身进行同步。对于静态方法,您正在同步到对象的类。因此,以下两段代码以相同的方式执行: 就像您写的一样。 如果要控制到特定对象的同步,或者只想将方法的 一部分 同步到该对象,则指定一个块。如果在方法声明上使用关键字,
我使用下面的代码来格式化日期。但是当我以不正确的格式给出数据时,它会给出意想不到的结果。 在上述情况下,输出为-formattedVal:0009-02-05。 它不是抛出解析异常,而是解析值并给我一个不正确的输出。有人能帮我理解这种反常的行为吗。