java线程同步问题,如何实现打印的j不重复

发布网友 发布时间:2022-04-25 13:17

我来回答

3个回答

热心网友 时间:2024-08-14 12:18

public class WebSource {

public static void main(String[] args) {
//提示用户输入开启的线程数
System.out.println("请输入您要开启的线程数,必须为整数,数值适当,否则可能挂机!");
Scanner sc = new Scanner(System.in);
int threadCount = sc.nextInt();
int j = 0;

MyThread mt = new MyThread(j);

for (int i = 0; i < threadCount; i++) {
new Thread(mt).start();
}
}
}

class MyThread implements Runnable {

private static int j = 10;

public MyThread(int j) {
}

public void run() {
getResourceURL();
}

//将存在资源的URL地址放到HashSet中去
public void getResourceURL() {
do {
if (j > 0) {
System.out.println(Thread.currentThread().getName() + " " + j--);
}
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(MyThread.class.getName()).log(Level.SEVERE, null, ex);
}
} while (j > 0);
}
}

说一下,synchronized 你用错了,你这样写的代码等同于单线程运行,当你第一个线程getResourceURL的时候第二个线程根本无法调用getResourceURL方法,非要等到前一个线程完毕然后下一个线程进来。如果说多线程是让几辆车同时运行在一条公路上,那同步synchronized 的目的是防止撞车,但是你synchronized 的目的是封锁公路,一次只让一辆车上路,这当然不会撞车,但是这已经不是多线程并行的初衷了。

热心网友 时间:2024-08-14 12:17

你好楼主,这个实现实现很简单,且看代码:

import java.util.Scanner;

public class WebSource
{
public static void main(String[] args)
{
//提示用户输入开启的线程数
System.out.println("请输入您要开启的线程数,必须为整数,数值适当,否则可能挂机!");
Scanner sc = new Scanner(System.in);
int threadCount = sc.nextInt();
int j = 0;

MyThread mt = new MyThread(j);

for(int i=0; i< threadCount; i++)
{
new Thread(mt).start();
System.out.println("启动线程"+i);
}
}
}

class MyThread implements Runnable
{
private int j;

public MyThread(int j)
{
this.j = j;
}

public void run()
{
getResourceURL();
}

//将存在资源的URL地址放到HashSet中去
public void getResourceURL()//这个方法去掉synchronized修饰
{
while(j<1000){//修改的地方
show();//新方法show完成输出和J自增
}
}
public synchronized void show(){//同步方法,输出与增加是同步的,严格保证不重复输出
if(j<1000){//
System.out.println(j);
j++;
}
}
}

改的就2处,改的地方我已经做出注释!
1 去掉getResourceURL()的synchronized修饰
2 把j的最大值改得更大一点
3 新增方法show,是同步的。保证不重复输出。

原来未达到要求原因:1 在synchronized的修饰下,getResourceURL()方法不能被多个线程同时调用,所以结果是,每个线程要等前面的线程执行完成后在调用,重新从1开始输出,导致重复。

现在真的好了,测试成功,OK!

热心网友 时间:2024-08-14 12:14

new MyThread(j);
参数 j 没什么意义啊

稍稍改动了一下你的程序:把 j 作为了类 WebSource 的全局变量,由它来控制所有内部线程类的同步打印:
public class WebSource{
private int j =0;
class MyThread implements Runnable {
public MyThread(int j) {
}

public void run() {
getResourceURL();
}

// 将存在资源的URL地址放到HashSet中去
public synchronized void getResourceURL() {
for (; j < 1000; j++) {
System.out.println(j);
}
}

}

public WebSource()
{
// 提示用户输入开启的线程数
System.out.println("请输入您要开启的线程数,必须为整数,数值适当,否则可能挂机!");
Scanner sc = new Scanner(System.in);
int threadCount = sc.nextInt();
int j = 0;

MyThread mt = new MyThread(j);

for (int i = 0; i < threadCount; i++) {
new Thread(mt).start();
}
}

public static void main(String[] args) {
new WebSource();
}
}

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com