2个线程在同一个实例的方法中输出
会出现如下结果:
zhangxiaoxiang
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuomizhangxiaoxiang
ng
zhangxiaoxiang
lihuoming
zhangxiaoxiang
zhangxiaoxiang
lihuoming
zhangxiaoxiang
lihuomizhangxiaoxiang
ng
zhangxiaoxiang
lihuoming
zhangxiaoxiang
如下代码可以产生错误的结果:
1、2个线程同时访问,output方法一个线程没有允许完成另一个线程就进来。
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("lihuoming"); } } }).start(); } class Outputer { public void output(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }
正确代码:
使用对象锁机制将输出体进行锁定
synchronized (this) { }
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("lihuoming"); } } }).start(); } class Outputer { public void output(String name) { int len = name.length(); synchronized (this) { for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } } }
2、错误代码
虽然两个线程调用的方法不同,可是还是在同一个对象中,当一个线程没有输出完毕的时候第二个线程就打印了
system.out.println();进行换行。
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output2("lihuoming"); } } }).start(); } class Outputer { public void output(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } public void output2(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }
正确代码:
synchronized 关键字加在方法上默认锁定this 对象 如果在方法中需要 使用synchronized(this){}
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output2("lihuoming"); } } }).start(); } static class Outputer { public void output(String name) { synchronized (this) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } public synchronized void output2(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }
错误代码:
因为一个线程调用的静态方法,即两个线程不是调用的同一个对象,也就说明synchronized不是锁定的同一个对象。
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } Outputer.output3("lihuoming"); } } }).start(); } static class Outputer { public void output(String name) { synchronized (this) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } public static synchronized void output3(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }
正确代码如下:
因为需要锁定静态对象 所以要使用Outputer.class
package cn.itcast.heima2; public class TraditionalTreadSynchrorized { public static void main(String[] args) { new TraditionalTreadSynchrorized().init(); } public void init() { final Outputer output = new Outputer(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } output.output("zhangxiaoxiang"); } } }).start(); new Thread(new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } Outputer.output3("lihuoming"); } } }).start(); } static class Outputer { public void output(String name) { synchronized (Outputer.class) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } public static synchronized void output3(String name) { int len = name.length(); for (int i = 0; i < len; i++) { System.out.print(name.charAt(i)); } System.out.println(); } } }