做了一个两个线程通讯的例子,为什么两个线程内循环还没结束程序就结束了?
下面是代码public class TestCommunication { public static void main(String[] args) {
Product p = new Product();
Producer ducer = new Producer(p);
Custom c = new Custom(p); c.start();
ducer.start();
}
}class Producer extends Thread{
private Product p;
public Producer(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.produce();
}
}}class Custom extends Thread{
private Product p;
public Custom(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.postProduct();
}
}
}
class Product{ private int product; private boolean canget=false;
synchronized void produce(){
if (canget){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+" producing..."+ ++product);
canget=true;
notify();
}
} synchronized void postProduct(){
try {
if (!canget){
wait();
}
else{
System.out.println(Thread.currentThread().getName()+" geting..."+ product);
canget=false;
notify();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}大家帮忙看看
下面是代码public class TestCommunication { public static void main(String[] args) {
Product p = new Product();
Producer ducer = new Producer(p);
Custom c = new Custom(p); c.start();
ducer.start();
}
}class Producer extends Thread{
private Product p;
public Producer(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.produce();
}
}}class Custom extends Thread{
private Product p;
public Custom(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.postProduct();
}
}
}
class Product{ private int product; private boolean canget=false;
synchronized void produce(){
if (canget){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+" producing..."+ ++product);
canget=true;
notify();
}
} synchronized void postProduct(){
try {
if (!canget){
wait();
}
else{
System.out.println(Thread.currentThread().getName()+" geting..."+ product);
canget=false;
notify();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}大家帮忙看看
for(int i=0; i<10;i++) {
System.out.println(i);
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.postProduct();
}
}
0
Thread-0 producing...1
1
Thread-1 geting...1
2
Thread-0 producing...2
Thread-1 geting...2
3
Thread-0 producing...3
Thread-1 geting...3
4
Thread-0 producing...4
5
Thread-1 geting...4
6
Thread-0 producing...5
Thread-1 geting...5
7
Thread-0 producing...6
Thread-1 geting...6
8
Thread-0 producing...7
Thread-1 geting...7
9
Thread-0 producing...8
Thread-1 geting...8
ducer.start();这两个的启动顺序换一下就可以了
至于为什么,你自己先分析一下程序的执行流程,看看会不会有一次被忽略
Thread-0 producing...1
1
Thread-1 geting...1
4
Thread-0 producing...4
5
Thread-1 geting...4
如下更改,注意红色处,再试试!
synchronized void produce(){
if (canget){
try {
wait();
System.out.println(Thread.currentThread().getName()+" producing..."+ ++product);
canget=true;
notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(Thread.currentThread().getName()+" producing..."+ ++product);
canget=true;
notify();
}
} synchronized void postProduct(){
try {
if (!canget){
wait();
System.out.println(Thread.currentThread().getName()+" geting..."+ product);
canget=false;
notify();
}
else{
System.out.println(Thread.currentThread().getName()+" geting..."+ product);
canget=false;
notify();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
消费者线程也同理,造成少调用一次循环。
因此造成数据减少修正的代码如下:
public class TestCommunication { public static void main(String[] args) {
Product p = new Product();
Producer ducer = new Producer(p);
Custom c = new Custom(p); ducer.start();
c.start();
}
}class Producer extends Thread{
private Product p;
public Producer(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.produce();
}
}}class Custom extends Thread{
private Product p;
public Custom(Product p){
this.p=p;
}
public void run(){
for(int i=0; i<10;i++) {
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.postProduct();
}
}
}
class Product{ private int product; private boolean canget=false;
synchronized void produce(){
try {
if (canget){
wait();
}
System.out.println(Thread.currentThread().getName()+" producing..."+ ++product);
canget=true;
notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} synchronized void postProduct(){
try {
if (!canget){
wait();
}
System.out.println(Thread.currentThread().getName()+" geting..."+ product);
canget=false;
notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
只修改了produce()和postProduct()的结构再次感谢各位