Java 同步不';这无助于实现相互排斥
C类: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++
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