Java 对于多线程共享资源,同步是更好的选择吗? 公共类MyResource{ 私有整数计数=0; 无效增量(){ 计数++; } void insert(){//增加共享资源计数 对于(int i=0;i

Java 对于多线程共享资源,同步是更好的选择吗? 公共类MyResource{ 私有整数计数=0; 无效增量(){ 计数++; } void insert(){//增加共享资源计数 对于(int i=0;i,java,multithreading,synchronized,Java,Multithreading,Synchronized,} 程序入口点是from entry()方法 1.仅使用insert();insert1();(普通方法调用)和注释startThread()(执行线程)会给出代码中所示的结果 2.现在插入注释();insert1();使用startThread()(执行线程)可以得到代码中所示的结果 3.现在我同步增量()以所用时间=35738 200000000的形式给出输出 如上所述,同步避免了对共享资源的访问,但另一方面,它需要大量的时间来处理 那么,如果同步会降低性能,那么它有什么用呢?您不应该使用同

}

程序入口点是from entry()方法

1.仅使用insert();insert1();(普通方法调用)和注释startThread()(执行线程)会给出代码中所示的结果

2.现在插入注释();insert1();使用startThread()(执行线程)可以得到代码中所示的结果

3.现在我同步增量()以所用时间=35738 200000000的形式给出输出

如上所述,同步避免了对共享资源的访问,但另一方面,它需要大量的时间来处理


那么,如果同步会降低性能,那么它有什么用呢?

您不应该使用同步来提高性能,而是应该使用同步来保护共享资源。 这是一个真实的代码示例吗?因为如果您想在这里使用线程来分割工作,请同步

public class MyResource {

private int count = 0;

void increment() {

    count++;

}

void insert() {    // incrementing shared resource count
    for (int i = 0; i < 100000000; i++) {
        increment();
    }

}

void insert1() {       //incrementing shared resource count
    for (int i = 0; i < 100000000; i++) {
        increment();
    }

}

void startThread() {

    Thread t1 = new Thread(new Runnable() {  //thread incrementing count using insert()

        @Override
        public void run() {
            insert();
        }
    });

    Thread t2 = new Thread(new Runnable() {    //thread incrementing count using insert1()

        @Override
        public void run() {
            insert1();
        }
    });

    t1.start();
    t2.start();

    try {
        t1.join(); //t1 and t2 race to increment count by telling current thread to wait
        t2.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

void entry() {
    long start = System.currentTimeMillis();
    startThread();            //commenting insert(); insert1() gives output as time taken = 452(approx)   110318544  (obvious)

    // insert(); insert1();     //commenting startThread() gives output as time taken = 452(approx)   200000000

    long end = System.currentTimeMillis();
    long time = end - start;
    System.out.println("time taken = " + time);

    System.out.println(count);
}
不是最好的方法

编辑 如上所述,您可以更改此特定代码的设计,以便更有效地在两个线程之间分配工作。 我修改了他们的示例以满足您的需要,但是这里描述的所有方法都很好

increment() 
import java.util.*;
导入java.util.concurrent.*;
导入静态java.util.Arrays.asList;
公共类金额{
静态类计数器实现可调用{
私人最终多头限额;
计数器(长限){
_极限=极限;
}
@凌驾
公共长途电话(){
长计数器=0;

对于(长i=0;i性能不是唯一的因素。正确性也可能非常重要。下面是另一个关于关键字的低级细节的问题

如果您正在寻找性能,请考虑使用类。它已被优化为快速原子访问。

编辑:

Synchonized在这个用例中是多余的。Synchronized对于FileIO或NetworkIO更有用,因为调用更长,正确性更重要。以下是的源代码。选择Volatile是因为它对于更改共享内存的短调用更为有效


添加synchronized关键字会添加额外的java字节码,该字节码会进行大量检查,以确保安全地获得锁。Volatile会将数据放入主内存,这需要更长的时间来访问,但CPU强制执行原子访问,而不是jvm在引擎盖下生成额外的代码。

有时,您只需要执行两个或更多的操作即可同时继续。想象一个聊天应用程序的服务器或一个程序在运行一个长任务时更新GUI,让用户知道正在进行处理

我从编程之洞获得了这段代码,并被我稍微扭曲了一下以学习同步………我首先尝试通过使用线程来提高性能,但结果是由于非原子性,它出乎意料,因此我尝试同步该方法,结果导致性能非常低…………最佳方法是什么?@Javed Solkar编辑了我的答案。还有一件事,有时你除了使用同步之外别无选择。在示例中,你发布的同步方法可能不是最佳方法,但在真正的系统,比如为数百个客户端提供多线程服务的应用服务器,同步是必须的。好吧,但是如果同步关键字降低了性能并提供了正确性,那么它有什么用呢。编辑我的答案来回答你的问题。同时进行两件或更多的事情,我将使用线程来完成。但是如果任何共享资源都必须使用同步,这将使应用程序速度慢于为什么使用同步?因为有时您没有其他选择,所以请根据应用程序要求交换性能
import java.util.*;
import java.util.concurrent.*;
import static java.util.Arrays.asList;

public class Sums {

    static class Counter implements Callable<Long> {

        private final long _limit;
        Counter(long limit) {
            _limit = limit;
        }

        @Override
        public Long call() {
            long counter = 0;
            for (long i = 0; i <= _limit; i++) {
                counter++
            }
            return counter;
        }                
    }

    public static void main(String[] args) throws Exception {

        int counter = 0;
        ExecutorService executor = Executors.newFixedThreadPool(2);
        List <Future<Long>> results = executor.invokeAll(asList(
            new Counter(500000), new Counter(500000));
        ));
        executor.shutdown();

        for (Future<Long> result : results) {
            counter += result.get();
        }                
    }    
}