使用synchronized代码块及其原理?
使用synchronized方法?
分析静态方法所使用的同步监视器对象是什么?
一、代码实现
1、同一对象锁
/**
* @Title: TraditionalThreadSynchronized.java
* @Package com.lh.threadtest
* @Description: TODO
* @author Liu
* @date 2018年1月15日 下午6:38:24
* @version V1.0
*/
package com.lh.threadtest.t3;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: TraditionalThreadSynchronized
* @Description: 传统线程互斥技术
* @author Liu
* @date 2018年1月15日 下午6:38:24
*
*/
public class TraditionalThreadSynchronized {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
new TraditionalThreadSynchronized().init();
}
private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("zhangsan");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("lisi");
}
}
}).start();
}
class Outputer{
public void output(String name){
String xxx = "xxx";
//不行,可以认为是不同的钥匙,不能起到互斥的效果
// synchronized (name) {
// for(int i = 0; i< name.length(); i++){
// System.out.print(name.charAt(i));
// }
// System.out.println();
// }
// synchronized (this) {
synchronized (xxx) {
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
2、外部调用对象(锁)不同
/**
* @Title: TraditionalThreadSynchronized.java
* @Package com.lh.threadtest
* @Description: TODO
* @author Liu
* @date 2018年1月15日 下午6:38:24
* @version V1.0
*/
package com.lh.threadtest.t3;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: TraditionalThreadSynchronized
* @Description: 传统线程互斥技术
* @author Liu
* @date 2018年1月15日 下午6:38:24
*
*/
public class TraditionalThreadSynchronized2 {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
new TraditionalThreadSynchronized2().init();
}
private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("zhangsan");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
// outputer.output("lisi");
//改成下面这种方式也是不行的(外部调用的对象不是同一个)!!!
new Outputer().output("lisi");
}
}
}).start();
}
class Outputer{
public void output(String name){
String xxx = "xxx";
//不行,可以认为是不同的钥匙,不能起到互斥的效果
// synchronized (name) {
// for(int i = 0; i< name.length(); i++){
// System.out.print(name.charAt(i));
// }
// System.out.println();
// }
// synchronized (this) {
synchronized (xxx) {
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
}
3、方法加synchronized关键字
/**
* @Title: TraditionalThreadSynchronized.java
* @Package com.lh.threadtest
* @Description: TODO
* @author Liu
* @date 2018年1月15日 下午6:38:24
* @version V1.0
*/
package com.lh.threadtest.t3;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: TraditionalThreadSynchronized
* @Description: 传统线程互斥技术
* @author Liu
* @date 2018年1月15日 下午6:38:24
*
*/
public class TraditionalThreadSynchronized3 {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
new TraditionalThreadSynchronized3().init();
}
private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("zhangsan");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("lisi");
}
}
}).start();
}
class Outputer{
//方法名前加synchronized关键字!对整个方法体加锁!
public synchronized void output(String name){
//线程间是互斥的!!
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
4、代码块synchronized修饰(与3所加的锁都是this(外部调用对象))
/**
* @Title: TraditionalThreadSynchronized.java
* @Package com.lh.threadtest
* @Description: TODO
* @author Liu
* @date 2018年1月15日 下午6:38:24
* @version V1.0
*/
package com.lh.threadtest.t3;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: TraditionalThreadSynchronized
* @Description: 传统线程互斥技术 (对象锁必须保证唯一性,即保证线程互斥性)
* @author Liu
* @date 2018年1月15日 下午6:38:24
*
*/
public class TraditionalThreadSynchronized4 {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
new TraditionalThreadSynchronized4().init();
}
private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("zhangsan");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output2("lisi");
}
}
}).start();
}
class Outputer{
//方法名前加synchronized关键字!对整个方法体加锁!
public void output(String name){
synchronized (this) {
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
//方法名前的synchronized使用的锁默认是当前对象!
public synchronized void output2(String name){
//线程间是互斥的!!
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
5、静态方法static加synchronized关键字(锁必须是Outputer.class)
/**
* @Title: TraditionalThreadSynchronized.java
* @Package com.lh.threadtest
* @Description: TODO
* @author Liu
* @date 2018年1月15日 下午6:38:24
* @version V1.0
*/
package com.lh.threadtest.t3;
import java.util.concurrent.TimeUnit;
/**
* @ClassName: TraditionalThreadSynchronized
* @Description: 传统线程互斥技术 (对象锁必须保证唯一性,即保证线程互斥性)
* @author Liu
* @date 2018年1月15日 下午6:38:24
*
*/
public class TraditionalThreadSynchronized5 {
/***
* @Title: main
* @Description: TODO
* @param @param args
* @return void
* @throws
*/
public static void main(String[] args) {
new TraditionalThreadSynchronized5().init();
}
private void init(){
final Outputer outputer = new Outputer();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("zhangsan");
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while(true){
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output3("lisi");
}
}
}).start();
}
static class Outputer{
//方法名前加synchronized关键字!对整个方法体加锁!
public void output(String name){
synchronized (Outputer.class) {
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
//方法名前的synchronized使用的锁默认是当前对象!
public synchronized void output2(String name){
//线程间是互斥的!!
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
//静态方法名前的synchronized使用的是class对象!
public static synchronized void output3(String name){
//线程间是互斥的!!
for(int i = 0; i< name.length(); i++){
System.out.print(name.charAt(i));
}
System.out.println();
}
}
}
二、注意点
1、内部类的作用:可以访问外部类的成员属性
来源:oschina
链接:https://my.oschina.net/u/3144678/blog/1607884