我有一个多线程的想法,但我从来没有工作过。所以,当我在工作中看到我的申请时.我还没有看到任何类扩展线程创建Thread。因此,当两个对象试图同时访问一个变量时,使用synchronized关键字。我们使用同步来避免冲突。
示例:
public class Test {
private static int count = 0;
public static synchronized void incrementCount() {
count++;
}
} 如果对象正在使用测试类,那么将synchronized添加到incrementcount()是有意义的。但是,当您不扩展Thread或Runnable时,编写synchronized的用途是什么。
发布于 2016-03-06 16:08:25
类不需要extend Thread或implements Runnable将其方法标记为同步以防止多线程访问
您的类可能是其他线程类的参数,而该线程类可能有多个实例。为了提供数据的强一致性,您必须保护代码和数据的关键部分。
只需更改代码示例,如下所示。
我演示的是"synchronized“,而不是类级别( static synchronized)。
class Test {
private int count = 0;
public void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
Test t = new Test();
for ( int i=0; i<10; i++){
new Thread(new MyRunnable(t)).start();
}
}
}您的类Test已作为参数传递给线程MyRunnable。现在,您已经创建了多个线程实例。在没有synchronized关键字的情况下,输出是不可预测的,如下所示。
java SynchronizedDemo
Count:2
Count:3
Count:2
Count:7
Count:6
Count:5
Count:4
Count:10
Count:9
Count:8如果我改变了
public void incrementCount() {至
public synchronized void incrementCount() {产出如下:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10另外,您已经将您的方法设置为static synchronized。That means lock is maintained at class level instead of object level.
查看甲骨文文档页面,以更好地理解。
没有"static synchronized“的代码演示
class Test {
private static int count = 0;
public static void incrementCount() {
count++;
System.out.println("Count:"+count);
}
}
class MyRunnable implements Runnable{
private Test test = null;
public MyRunnable(Test t){
this.test = t;
}
public void run(){
test.incrementCount();
}
}
public class SynchronizedDemo{
public static void main(String args[]){
for ( int i=0; i<10; i++){
Test t = new Test();
new Thread(new MyRunnable(t)).start();
}
}
}产出:
Count:5
Count:4
Count:3
Count:2
Count:10
Count:9
Count:8
Count:7
Count:6制作后
public static void incrementCount() {至
ppublic static synchronized void incrementCount() {产出:
Count:1
Count:2
Count:3
Count:4
Count:5
Count:6
Count:7
Count:8
Count:9
Count:10在这个例子中,与前面的不同,我们创建了10个不同的Test实例。
发布于 2016-03-05 03:10:47
同步不是用于线程或Runnable,而是用于由多个线程访问的数据结构,以确保每个线程以不破坏其数据的方式访问它们。您自己的示例是这种情况的基本情况,计数以非threadsafe (使用++,请参阅此问题)的方式递增,因此需要锁定以确保一次只能增加一个线程。
如果有其他访问计数的代码,那么它也需要同步,这样它就可以看到对count的更新。如果您所做的只是递增一个计数器,那么使用像java.util.concurrent.atomic.AtomicInteger这样的类就更有意义了,而且您可以完全不使用同步关键字。
为了使同步化有意义,它确实假定存在多个线程。即使您自己的代码没有创建新线程,也可能存在多个线程正在调用您的代码的情况(例如在servlet容器中,容器管理线程池并为每个传入请求分配一个线程)。
发布于 2016-03-05 03:14:07
i++,即使它看起来像一个指令,实际上是多个指令:
1+i。i设置为临时变量。但是,假设执行i++的线程在步骤1之后被中断,而中断线程也调用i++。然后,这种情况就会发生:
(假设i=1)
1+i或2。i+1,也将2设置为i设置为临时variable2。现在i=2i设置为临时variable1。现在i=2问题是,如果i++被两次调用,那么它应该是3,而不是2。
synchronized void将对变量i设置一个锁,直到整个void完成执行。例如:
1+i或2。对变量i设置一个锁。i+1,但由于变量i上的锁而等待i设置为临时variable1。现在是i=2。变量i现在已解锁。i已被解锁,因此它将临时variable2设置为i+1,即3。i设置为3,这是预期的行为。synchronized void本质上是暂时锁定变量,以避免混淆程序的执行。
https://stackoverflow.com/questions/35809464
复制相似问题