JavaSE之实现多线程和解决线程安全问题

实现多线程的两种方式

方式一:继承Thread类

1.具体步骤

1.1:创建一个继承Thread类的子类

public class ThreadChild extends Thread {
}

1.2:重写Thread类中的run()方法,将目标操作放在run()方法中

public class ThreadChild extends Thread{
	@Override
    public void run() {
        //目标操作的代码
    }
}
	

1.3:创建子类的对象

ThreadChild tc1 = new ThreadChild();
ThreadChild tc2 = new ThreadChild();
ThreadChild tc2 = new ThreadChild();

1.4:子类对象调用start()方法

tc1.start();
tc2.start();
tc3.start();

方式二:实现Runnable接口

1.具体步骤

1.1:创建一个实现Runnable()接口的实现类

public class ThreadTest implements Runnable {

}

1.2:重写run()方法,将目标操作放在run()方法中

public class ThreadTest implements Runnable {
    @Override
    public void run() {
        //目标操作代码
    }
}

1.3:创建实现类对象

ThreadTest tt = new ThreadTest();

1.4:将实现类对象作为参数传递到Thread()构造器中,创建Thread类对象

Thread t1 = new Thread(tt);
Thread t2 = new Thread(tt);
Thread t2 = new Thread(tt);

1.5:Thread类对象调用start()方法

t1.start();
t2.start();
t3.start();

推荐使用实现Runnable()接口的方式实现多线程

---------------------------------------------------------------------------

解决线程安全问题synchronized

什么是线程安全问题?

多个线程共享同一资源,导致共享资源更新不及时

方法一:同步代码块

synchronized(同步监视器){
//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
}

注:需要被同步的代码要全部写入到同步代码块中,不可将其余代码写入,也不可缺少有关代码

同步监视器

又称为同步锁,具有唯一性,多个线程抢同步锁,哪个线程抢到锁就执行同步代码,其余线程等待锁被释放

哪些可以成为同步监视器?

1.任一类的对象
2.this
3.Sring字符串
4.当前类.class

1.同步代码块+实现Runnable()接口

public class ThreadTest implements Runnable {
    @Override
    public void run() {
        //其他执行操作
        //...
        synchronized(同步监视器){
			//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
		}
		//...
    }
}

2.同步代码块+继承Thread类

public class ThreadChild extends Thread{
	@Override
    public void run() {
    	//其他执行操作
        //...
        synchronized(同步监视器){
			//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
		}
		//...
    }
    }
}
	

通过继承Thread类的方式实现多线程,创建了多个Thread类的对象,如果此时的同步监视器采用任一类的对象,要保证对象唯一,可以用static修饰;this做同步监视器也违反了唯一性。使用当前类类名.class就可以完美解决问题

synchronized(ThreadChild.class){
			//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
		}

方法二:同步方法

将需要被同步的代码放在一个方法中,使用synchronized定义方法
同步方法仍然涉及到同步监视器,只是不需要显式的声明
非静态同步方法默认的同步监视器是:this
静态同步方法默认的同步监视器是:当前类的类类对象 —> 当前类.class

权限修饰符 synchronized 返回类型 方法名(){
	//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
}

1.同步方法+实现Runnable()接口

public class ThreadTest implements Runnable {
    @Override
    public void run() {
        方法名();
    }
    权限修饰符 synchronized 返回类型 方法名(){  //同步监视器:this(当前对象)
	//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
	}
}

2.同步方法+继承Thread类

public class ThreadChild extends Thread{
	 @Override
    public void run() {
        方法名();
    }
    权限修饰符 synchronized 返回类型 方法名(){
	//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
	}
}

此时同步方法使用的锁对象默认是this,而继承Thread类实现多线程创建了多个当前对象,此时的锁对象不唯一,因此照旧会出现线程安全问题。
解决方法:将同步方法添加static修饰。注:此时方法体中如果含有调用其他方法,只能调用静态方法

权限修饰符 static synchronized 返回类型 方法名(){ //同步监视器:当前类.class  ThreadChild.class
	//需要被同步的代码 ----> 和共享数据有关的操作都需要被同步
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值