线程实现的方式
1、extents thread
2、implememts runnable
由于多线程是异步的,所有会产生线程安全问题。
线程安全:就是多线程访问时,加同步锁,当一个线程访问该类的成员变量【类中方法外】,其他线程不能进行行访问直到该线程读取完,其他线程才可使用,也就是不会出现数据不一致或者数据污染。
相对来说就是线程不安全:不提供数据访问保护,导致的多个线程对同一对象中的变量进行并发访问时产生的脏数据,
由上面引起:多线程下对类的成员变量的读写操作引起的。
成员变量分为:
静态属性【类变量,static修饰】:随类的存在而存在,是在类加载的初始化
非静态属性【类的实例变量】:随实例的属性存在而存在。
局部变量:
局部变量不能加static,包括protected, private, public这些也不能加。局部变量保存在栈中。
局部编程必须在声明时初始化。
非线程安全的解决方法是什么???
1、把对象设置成不带属性。将对象设置成无状态的,不带属性就不存在多线程对变量的读取、修改。
2、设置成局部变量(方法内的变量,不是类变量)?为啥?多线程调用同一个对象的方式时,方法内的对象是私有的
3、用ThreadLocal,为每个线程都创建一个对象。
4、同步方法:加同步锁[互斥锁],按照顺序排队访问 synthronized、lock
例如:synthronized public void run(){}
1、方法内的变量为线程安全,这是由于方法内的变量是私有的特性造成的。
2、实例变量是非线程安全的,暨在一个方法外,类内,解决方法:加 synchronized关键字。
1、同步方法:暨同步对象,对象锁,不是把一段代码或者方法(函数)当做锁。多个同步方法呢?
2、同步代码快:
A: synchronized(this)、<===>同步方法,也是锁定当前对象。
B: synchronized(string) 又分成员变量(一个和多个)和形参、 变量的情况分为一个
3、synchronized static 静态同步方法 同下 类锁
4、synchronized(Class) 同步类 同上 类锁
5、类锁和对象锁有什么区别?他们是相互独立不冲突的,获取了类锁的线程和获取了对象锁的线程是不冲突的!
以上又分为以下几种情况:
1、线程的多个对象和一个对象
2、多个同步方法,全部同步,容易造成死锁,解决方案:同步块
3、一个同步方法和没有同步的方法的调用
4、多个线程调用 同步A、同步B
5、死锁
6、脏数据
demo:
public class Mythread extends Thread {
private static int count = 5;
private static ReentrantLock lock =new ReentrantLock();
@Override
synchronized public void run() { // 方法锁
count --;
System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
}
// @Override
// synchronized static public void run() { // 静态方法锁,等价于类锁
// count --;
// System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
// }
// @Override
// public void run() {
//
// super.run();
// synchronized(this) { // 对象锁
// count --;
// System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
// }
// }
// @Override
// public void run() {
//
// super.run();
// synchronized(Mythread.class) { // 类锁
// count --;
// System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
// }
// }
// @Override
// public void run() { // ReentrantLock
//
// try{
// lock.lock();
// count --;
// System.out.println("---- this name is " + this.currentThread().getName() + "value is :" +count);
// }
// finally
// {
// lock.unlock();
// }
// }
public static void main(String args[]) {
Mythread mythread = new Mythread();
Thread a = new Thread(mythread, "A");
Thread b = new Thread(mythread, "B");
Thread c = new Thread(mythread, "C");
Thread d = new Thread(mythread, "D");
a.start();
b.start();
c.start();
d.start();
}
}
参考:https://www.cnblogs.com/xumanbu/p/4203504.html JAVA中 成员变量和和实例变量区别