1. 创建线程的方式
创建线程的方式有四种,见之前的博文
2. 解决线程安全问题的方式
同步代码块、同步方法,都可以解决线程安全问题
不同的创建线程的方式,都可以加入同步代码块和同步方法解决线程安全问题,那么组合起来就一共有4 * 2 = 8种写法。
以下只列出4中写法:
1. 同步方法-继承Thread类
2. 同步方法-实现Runnable接口
3. 同步代码块-继承Thread类
4.同步代码块-实现Runnable接口
3.代码示例
3.1. 同步方法-继承Thread类
同步方法仍然涉及到同步监视器,只是不需要我们显式的声明。非静态的同步方法,同步监视器是this。静态的同步方法,同步监视器是:当前类本身(Xxx.class,类Xxx加载时产生的对象,运行时类)
//SynchronizedMethodTest1.java
package com.ylaihui.thread;
class ProcMsg extends Thread{
private static int message = 100;
@Override
public void run() {
while(true){
proc();
}
}
// private synchronized void proc(){ // 同步监视器是 this, 是 t1 t2 t3
private static synchronized void proc(){ // 同步监视器是 ProcMsg.class 对象
if(message > 0){
System.out.println(Thread.currentThread().getName() + ":" + message);
message--;
}
}
}
public class SynchronizedMethodTest1 {
public static void main(String[] args) {
ProcMsg t1 = new ProcMsg();
ProcMsg t2 = new ProcMsg();
ProcMsg t3 = new ProcMsg();
t1.start();
t2.start();
t3.start();
}
}
3.2 同步方法-实现Runnable接口,代码中只new了一个ProcessMessage2类型的对象,该对象可以充当锁。
//SynchronizedMethodTest.java
package com.ylaihui.thread;
import static java.lang.Thread.sleep;
class ProcessMessage2 implements Runnable{
private int message = 100;
@Override
public void run() {
while(true) {
proc();
}
}
private synchronized void proc(){ // 同步监视器是 this
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(message > 0) {
System.out.println("process message: " + Thread.currentThread().getName() + "-" + message);
message--;
}
}
}
public class SynchronizedMethodTest {
public static void main(String[] args) {
ProcessMessage2 p = new ProcessMessage2();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
t1.start();
t2.start();
t3.start();
}
}
3.3 同步代码块-继承Thread类
class ProcessMsg extends Thread{
private static int message = 100;
private static Object obj = new Object();
@Override
public void run() {
// 方式一
// synchronized(obj){
// ProcessMsg 在运行时只加载一次, 在底层也是一个对象
synchronized(ProcessMsg.class){
while(true){
if(message > 0 ){
System.out.println("process message: " + message);
message--;
}else
break;
}
}
}
}
public class ThreadSynchronizedBlock1 {
public static void main(String[] args) {
ProcessMsg t1 = new ProcessMsg();
ProcessMsg t2 = new ProcessMsg();
ProcessMsg t3 = new ProcessMsg();
t1.start();
t2.start();
t3.start();
}
}
3.4 同步代码块-实现Runnable接口
//ThreadSynchronizedBlock.java
package com.ylaihui.thread;
class ProcessMessage1 implements Runnable{
private int message = 100;
Object obj = new Object();
@Override
public void run() {
// synchronized(obj){
synchronized(this){
while(true){
if(message > 0){
System.out.println("process message: "+ message);
message--;
}else
break;
}
}
}
}
public class ThreadSynchronizedBlock {
public static void main(String[] args) {
ProcessMessage1 p = new ProcessMessage1();
Thread t1 = new Thread(p);
Thread t2 = new Thread(p);
Thread t3 = new Thread(p);
t1.start();
t2.start();
t3.start();
}
}