每次运行此程序时,我都会得到不同的输出。 有没有办法只在run方法中获得一致的输出?
public class MultiBasic1 {
public static void main(String[] args) {
ChildThread th1=new ChildThread();
ChildThread th2= new ChildThread();
ChildThread th3= new ChildThread();
ChildThread th4= new ChildThread();
th1.start();
th2.start();
th3.start();
th4.start();
}
}
class ChildThread extends Thread{
synchronized public void run(){
for(int i=1; i<=5; i++)
System.out.println(i);
}
}
答案 0 :(得分:2)
因为您正在创建ChildThread
的新实例,所以允许每个线程无限制地访问run
方法,因为实际只有一个线程正在访问该方法。
要演示synchronized
如何工作,您需要拥有某种共享资源,例如每个线程可以与之交互的Object
public class Test {
public static void main(String[] args) {
Action action = new Action();
Thread t1 = new Thread(new Runner(action), "1");
Thread t2 = new Thread(new Runner(action), "2");
Thread t3 = new Thread(new Runner(action), "3");
Thread t4 = new Thread(new Runner(action), "4");
Thread t5 = new Thread(new Runner(action), "5");
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
public static class Runner implements Runnable {
private Action action;
public Runner(Action action) {
this.action = action;
}
@Override
public void run() {
action.makeItSo();
}
}
public static class Action {
public synchronized void makeItSo() {
for (int index = 0; index < 10; index++) {
System.out.println(Thread.currentThread().getName() + " - " + index);
}
}
}
}
上面的示例演示了只有一个线程可以在makeItSo
方法中运行,但是,也不能保证允许哪个线程运行(即顺序)
答案 1 :(得分:1)
为什么你得到不同的输出?
答案: synchronized在进入同步块或方法之前需要一个锁定对象。
在这种情况下,对执行该方法的对象进行锁定,因此线程1锁定在对象th1上,线程2锁定在th2上,依此类推。
因此,所有线程都锁定到不同的对象上,并允许它们同时运行。
如何获得一致的输出?
答案
选项1:您可以使用join将线程连接到主线程 公共类MultiBasic1 {
public static void main(String[] args) throws InterruptedException {
ChildThread th1=new ChildThread();
ChildThread th2= new ChildThread();
ChildThread th3= new ChildThread();
ChildThread th4= new ChildThread();
th1.setName("A");
th2.setName("B");
th3.setName("C");
th4.setName("D");
th1.start();
th1.join();
th2.start();
th2.join();
th3.start();
th3.join();
th4.start();
th4.join();
}
}
class ChildThread扩展了Thread {
public void run(){
for(int i=1; i<=5; i++)
System.out.println(i + " " + getName());
}
}
选项2:为synchronized块提供共享对象以同步线程
公共类MultiBasic1 {
public static void main(String[] args) throws InterruptedException {
ChildThread th1=new ChildThread();
ChildThread th2= new ChildThread();
ChildThread th3= new ChildThread();
ChildThread th4= new ChildThread();
th1.setName("A");
th2.setName("B");
th3.setName("C");
th4.setName("D");
th1.start();
th2.start();
th3.start();
th4.start();
}
}
class ChildThread扩展了Thread {
private static final Object lock = new Object();
public void run(){
synchronized (lock) {
for(int i=1; i<=5; i++)
System.out.println(i + " " + getName());
}
}
}
答案 2 :(得分:0)
这里甚至不需要同步,因为您使用不同的对象来调用run方法。
当一个对象的多个线程在图片中时,同步有效。
如果您执行以下操作,上面的示例会更有意义。
public class MultiBasic1 {
public static void main(String[] args) {
ChildThread th1=new ChildThread();
Thread t1 = new Thread(th1);
Thread t2 = new Thread(th1);
Thread t3 = new Thread(th1);
Thread t4 = new Thread(th1);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class ChildThread extends Thread{
synchronized public void run(){
for(int i=1; i<=5; i++)
System.out.println(i);
}
}