Java线程无法同步
我刚开始使用notify、synchronized和wait,它几乎可以工作,但只有当我让第二个线程sleep()保持1毫秒时,它才能工作。最后你可以看到我的控制台输出 我的主要意见是:Java线程无法同步,java,multithreading,synchronization,Java,Multithreading,Synchronization,我刚开始使用notify、synchronized和wait,它几乎可以工作,但只有当我让第二个线程sleep()保持1毫秒时,它才能工作。最后你可以看到我的控制台输出 我的主要意见是: public static void main(String[] args) { InfoPaket paket = new InfoPaket(); TestThread testThread = new TestThread(paket); TestThread2 testThre
public static void main(String[] args) {
InfoPaket paket = new InfoPaket();
TestThread testThread = new TestThread(paket);
TestThread2 testThread2 = new TestThread2(paket);
}
我的“锁”类
我的两个测试线程
一,
二,
等等
但是把2。线程每次睡眠都会减慢程序的速度,
但如果没有它,我会有一些奇怪的事情,我无法向自己解释:
waiting
here 1
he got it... lelaoao 1
he got it... lelaoao 2
waiting
here 2
here 3
he got it... lelaoao 3
he got it... lelaoao 4
waiting
here 4
here 5
here 6
here 7
here 8
here 9
here 10
he got it... lelaoao 5
he got it... lelaoao 6
waiting
你的代码按预期工作(按编码),除了-1)你有一些坏代码2)你可能误解了这个概念 首先让我说一下您的代码在做什么:
InfoPaket
,它在两个线程之间共享,并保存有关数据包的信息,并跟踪是否收到新信息TestThread
,它将检查是否收到新信息,如果没有收到新信息,它将等待,一旦收到新信息,你将打印信息(始终为“lelaao”)以及循环计数器,就像这样他得到了它。。。乐老奥23
TestThread2
,它将设置信息并通知等待的线程,然后像这样打印该线程的循环计数器-“here”+i
thread.sleep(1)
或Thread.yeild()
,请注意Thread.yeild()
不可移植,最好不要使用它,也不要使用它,而应该使用Thread.sleep(1)
现在,让我们来看看糟糕的代码和一些重要的概念:
错误代码
TestThread2
中引用当前线程,因为您可以直接执行thread.sleep(1)代码>将导致当前线程休眠
System.out.println(“他知道了…”+info+“”+i)代码>和系统输出打印项次(“此处”+i)代码>来自主线程,但是您应该从同步块打印这些,以确保没有交错,因为在没有同步的情况下,可能会发生交错,您可以看到他得到了它。。。Lelaao 3
之前的这里的3
在逻辑上是错误的
public class InfoPaket {
String info;
char infoDataSign;
boolean newInfo = false;
public synchronized boolean isNew() {
if (!newInfo) {
try {
System.out.println("waiting");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return newInfo;
}
public synchronized void getInfo(int i) {
newInfo = false;
System.out.println("he got it... " + info + " " + i);
}
public synchronized void setInfo(String info, int i) {
this.info = info;
newInfo = true;
System.out.println("here " + i);
notify();
}
public static void main(String[] args) {
InfoPaket paket = new InfoPaket();
TestThread testThread = new TestThread(paket);
TestThread2 testThread2 = new TestThread2(paket);
new Thread(testThread, "testThread").start();
new Thread(testThread2, "testThread2").start();
}
}
public class TestThread implements Runnable {
InfoPaket info;
int i = 0;
public TestThread(InfoPaket info) {
this.info = info;
}
public void run() {
while (true) {
i++;
getInfo(i);
}
}
void getInfo(int i2){
info.isNew();
info.getInfo(i2);
}
}
public class TestThread2 implements Runnable {
InfoPaket info;
int i = 0;
public TestThread2(InfoPaket info) {
this.info = info;
}
public void run() {
while (i < 500000) {
i++;
setInfo(i);
}
}
void setInfo(int i2) {
info.setInfo("lelaoao", i2);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TestThread.java
public class InfoPaket {
String info;
char infoDataSign;
boolean newInfo = false;
public synchronized boolean isNew() {
if (!newInfo) {
try {
System.out.println("waiting");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return newInfo;
}
public synchronized void getInfo(int i) {
newInfo = false;
System.out.println("he got it... " + info + " " + i);
}
public synchronized void setInfo(String info, int i) {
this.info = info;
newInfo = true;
System.out.println("here " + i);
notify();
}
public static void main(String[] args) {
InfoPaket paket = new InfoPaket();
TestThread testThread = new TestThread(paket);
TestThread2 testThread2 = new TestThread2(paket);
new Thread(testThread, "testThread").start();
new Thread(testThread2, "testThread2").start();
}
}
public class TestThread implements Runnable {
InfoPaket info;
int i = 0;
public TestThread(InfoPaket info) {
this.info = info;
}
public void run() {
while (true) {
i++;
getInfo(i);
}
}
void getInfo(int i2){
info.isNew();
info.getInfo(i2);
}
}
public class TestThread2 implements Runnable {
InfoPaket info;
int i = 0;
public TestThread2(InfoPaket info) {
this.info = info;
}
public void run() {
while (i < 500000) {
i++;
setInfo(i);
}
}
void setInfo(int i2) {
info.setInfo("lelaoao", i2);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
TestThread2.java
public class InfoPaket {
String info;
char infoDataSign;
boolean newInfo = false;
public synchronized boolean isNew() {
if (!newInfo) {
try {
System.out.println("waiting");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return newInfo;
}
public synchronized void getInfo(int i) {
newInfo = false;
System.out.println("he got it... " + info + " " + i);
}
public synchronized void setInfo(String info, int i) {
this.info = info;
newInfo = true;
System.out.println("here " + i);
notify();
}
public static void main(String[] args) {
InfoPaket paket = new InfoPaket();
TestThread testThread = new TestThread(paket);
TestThread2 testThread2 = new TestThread2(paket);
new Thread(testThread, "testThread").start();
new Thread(testThread2, "testThread2").start();
}
}
public class TestThread implements Runnable {
InfoPaket info;
int i = 0;
public TestThread(InfoPaket info) {
this.info = info;
}
public void run() {
while (true) {
i++;
getInfo(i);
}
}
void getInfo(int i2){
info.isNew();
info.getInfo(i2);
}
}
public class TestThread2 implements Runnable {
InfoPaket info;
int i = 0;
public TestThread2(InfoPaket info) {
this.info = info;
}
public void run() {
while (i < 500000) {
i++;
setInfo(i);
}
}
void setInfo(int i2) {
info.setInfo("lelaoao", i2);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
需要明确的重要概念
我认为您可能缺少一些概念,所以您认为输出是疯狂的
thread.yield()
和thread.sleep()
开头强调了关于这一点的更多内容。注意,如果您不使用Thread.sleep(1)
,那么您就不能期望输出是一致的,正如我在下面所示Thread.sleep
时,如果该线程正在获取一些锁,那么它不会释放锁notify()
那么您不能期望等待的线程立即“可运行”,并且获取锁的线程不会在notify()时立即释放锁调用code>时,只有在同步块/方法完成后才会释放锁
Thread.sleep(1)
,那么您就不能期望一致的输出,以及我上面解释的原因OP评论:
你知道有什么更有效的方法从网上传送数据吗 把线接到另一个
您拥有“共享内存”或“消息传递”;在这种情况下,共享内存就是我们正在做的事情,如果你想进行消息传递,那么你可以使用Java API,比如阻塞队列()实现,但这完全是另一回事。“但是每次休眠2.线程都会减慢程序的速度。但是如果没有消息传递,我就无法向自己解释一些疯狂的事情。”..线程应表现良好。线程1不睡眠也不等待,因为get info方法也不等待,所以您具有失控线程的特性。线程化所节省的时间必须大于与线程化相关的成本synchronization@RajeevRanjan更好吗?=)@什么是T台线程?为什么不等待呢?因为它会打印“等待”?看看线程1。循环不睡眠。它调用getInfo,它只做一件事:获取新信息。当线程2休眠时,线程1可以在一毫秒内执行几百次。如果这对你有帮助,我将把它作为一个答案发布。非常感谢你的代码和解释=)你还没有发现OP代码中的所有错误。睡眠应该是不必要的。你知道有什么更有效的方法将数据从一个线程传输到另一个线程吗?@NathanHughes Sleeping(1毫秒)让thread1在没有
线程的情况下运行。睡眠(1)
在