Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同步不';这无助于实现相互排斥_Java_Multithreading_Thread Safety - Fatal编程技术网

Java 同步不';这无助于实现相互排斥

Java 同步不';这无助于实现相互排斥,java,multithreading,thread-safety,Java,Multithreading,Thread Safety,C类: class C extends Thread { public static int cr; C(int n) { cr = n; } public void run() { go(); } synchronized void go() { for (int i = 0; i < 10000; i++) { cr++

C类:

class C extends Thread
{
    public static int cr;

    C(int n) 
    {
        cr = n;
    }

    public void run()
    {
        go();
    }

    synchronized void go()
    {
        for (int i = 0; i < 10000; i++)
        {
            cr++;
        }
    }
}
C类扩展线程
{
公共静态int-cr;
C(int n)
{
cr=n;
}
公开募捐
{
go();
}
同步的void go()
{
对于(int i=0;i<10000;i++)
{
cr++;
}
}
}
班级启动

class Launch
{
    public static void main(String args[]) throws InterruptedException
    {
        C[] c = new C[10];

        for (int i = 0; i < 10; i++)
        {
            c[i] = new C(0);
        }

        for (int i = 0; i < 10; i++)
        {
            c[i].start();
        }

        System.out.println(C.spaces);
    }
}
类启动
{
公共静态void main(字符串args[])引发InterruptedException
{
C[]C=新的C[10];
对于(int i=0;i<10;i++)
{
c[i]=新的c(0);
}
对于(int i=0;i<10;i++)
{
c[i].start();
}
System.out.println(C.spaces);
}
}
它没有给我10万,而是10万以下的数字。为什么?我使方法
go()
同步,所以一次只能由一个线程使用。。?我错过了什么?

 c[i] = new C(0);
您每次都在创建新的c实例

如果一次只有一个线程,则不需要同步(多线程概念)。

synchronized void go(){…}
意味着它在当前实例上是同步的(在
上)。由于此方法属于自定义线程类,并且您正在装入10个线程,因此存在10个不同的
引用

这就是为什么不扩展Thread类,而是实现
Runnable
接口并将此接口的实例传递给任意多个线程的原因之一

另一个问题是,您正在打印编辑的值,而不等待线程完成

您需要的是创建一个实例,该实例将保存您要更改的值,并仅从一个实例调用synchronized方法,因为默认情况下,
synchronized void方法
上同步(调用此方法的当前对象)

类MyTask实现可运行{
公共易失性计数器;
我的任务(int n){
计数器=n;
}
公开募捐{
System.out.println(Thread.currentThread().getName()+“entered run”);
go();
System.out.println(Thread.currentThread().getName()+“finished run”);
}
同步的void go(){
System.out.println(Thread.currentThread().getName()+“输入go”);
对于(int i=0;i<10000;i++){
计数器++;
}
System.out.println(Thread.currentThread().getName()+“左起”);
}
}
班级午餐{
公共静态void main(字符串args[])引发InterruptedException{
//让我们创建要并行执行的任务
MyTask任务=新的MyTask(0);
线程[]线程=新线程[10];
for(int i=0;i<10;i++)//创建线程实例
线程[i]=新线程(任务);
对于(inti=0;i<10;i++)//启动线程
线程[i].start();
对于(int i=0;i<10;i++)
线程[i].join();//保持主线程等待所有线程完成
System.out.println(任务计数器);
}
}
它没有给我10万,而是给了10万以下的数字。为什么? 一切正常,但
main
线程没有等待其他线程完成计算,因此
main
线程中的输出是随机的

使用此选项,以便主线程在执行主线程的最后一行之前等待所有其他线程死亡

for (int i = 0; i < 10; i++) {
    c[i].start();
    c[i].join(); // Waits for this thread to die
}

System.out.println(C.cr); // output 100000
for(int i=0;i<10;i++){
c[i].start();
c[i].join();//等待此线程死亡
}
System.out.println(C.cr);//产量100000


它值得一读

它同步了什么?它没有给我100000,因为主线程没有等待其他线程完成。@Braj我知道。这是我在回答中提到的另一个问题。@Pshemo beauty,非常感谢,我想我现在明白了@Pshemo虽然我不知道如果我们只有一个对象任务它是如何工作的。。。我们怎么能在同一个对象上有10个不同的线程呢?好的,让我们看看你在哪里丢失了。您知道
synchronized void foo(){…}
实际上与
void foo(){synchronized(this){…}}
相同吗?非常感谢。但现在即使没有同步,我也能得到100000美元…:(我什么都不懂…编辑:对不起,我应该加入另一个循环。现在一切都按我预想的那样工作,再次感谢!编辑2:事实上,如果我加入了另一个循环,即使go已同步,它也不会给我100k:(同步不是问题。问题在于在等待其他线程完成计算之前打印值的
main
线程。这可能有助于我为(int I=0;I<10;I++){c[I].start();}for(int I=0;I<10;I++){c[I].join();},但即使go是同步的,它也不会给我100k。@Ijustwant2了解如果线程
A
在线程
B
上调用
join
,那么
A
将等待
B
完成。在这种情况下,主线程运行
c[i]。start()
并立即
c[i]。join()
这意味着在它将迭代到下一个线程
c[i+1]
并启动它之前,它将等待
c[i]
完成,因此这里没有并行性,因为一次只有一个线程可以工作。@Pshemo查看我上面的评论,我将join和start分离到不同的循环中。
I made method go() synchronized, so it should be used by only one thread at a time..?
class MyTask implements Runnable {

    public volatile int counter;

    MyTask(int n) {
        counter = n;
    }

    public void run() {
        System.out.println(Thread.currentThread().getName()+" entered run");
        go();
        System.out.println(Thread.currentThread().getName()+" finished run");
    }

    synchronized void go() {

        System.out.println(Thread.currentThread().getName()+" entered go");
        for (int i = 0; i < 10000; i++) {
            counter++;
        }
        System.out.println(Thread.currentThread().getName()+" left from go");
    }
}

class Luncher {
    public static void main(String args[]) throws InterruptedException {

        //lets create task we want to execute in parallel
        MyTask task = new MyTask(0);

        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++)//create thread instances
            threads[i] = new Thread(task);

        for (int i = 0; i < 10; i++)//start threads
            threads[i].start();

        for (int i = 0; i < 10; i++)
            threads[i].join();//hold main thread to wait till all threads will finish
        System.out.println(task.counter);
    }
}
for (int i = 0; i < 10; i++) {
    c[i].start();
    c[i].join(); // Waits for this thread to die
}

System.out.println(C.cr); // output 100000