多线程学习(二):线程间的数据共享

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengsheng5210/article/details/85042158

数据不共享的情况

public class MyThread04 extends Thread{
	private int count=5;
	public MyThread04(String threadName) {
		this.setName(threadName);
	}
	
	@Override
	public void run() {
		while(count>0){
			count--;
			System.out.println(Thread.currentThread().getName()+"-----"+count);
		}
	}
	public static void main(String[] args) {
		new MyThread04("第一个线程").start();
		new MyThread04("第二个线程").start();
		new MyThread04("第三个线程").start();
	}
}

运行结果

在这里插入图片描述
上述创建了3个对象,这3个对象的数据是互相不共享的。

数据共享的情况

public class MyThread05 extends Thread{
	private int count=5;
	@Override
	public void run() {
		count--;
		System.out.println(Thread.currentThread().getName()+"-----"+count);
	}
	public static void main(String[] args) {
		MyThread05 myThread05=new MyThread05();
		new Thread(myThread05,"第一个线程").start();
		new Thread(myThread05,"第二个线程").start();
		new Thread(myThread05,"第三个线程").start();
		new Thread(myThread05,"第四个线程").start();
		new Thread(myThread05,"第五个线程").start();
	}
}

运行结果

在这里插入图片描述
上述运行的5个线程,使用的数据都是一个对象的数据,即count变量是共享的,所以出现了“非线程安全”的问题(非线程安全指多个线程对同一个对象中的同一个实例变量进行操作时会出现值被更改、值不同步的情况,进而影响程序的执行流程)。
出现count一样的情况,可以使用synchronized关键字来避免。
在这里插入图片描述

运行结果

在这里插入图片描述
synchronized修饰的方法或代码块,这段加锁的代码称为“互斥区”或“临界区”。

i–与System.out.println()的异常

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

currentThread()方法

currentThread()方法是一个static方法,它可以返回当前代码正在被哪个线程调用的信息。

public class MyThread01 extends Thread{
	@Override
	public void run() {
		System.out.println("子线程名:"+Thread.currentThread().getName());
	}

	public static void main(String[] args) {
		new MyThread01().start();  //调用子线程
		System.out.println("主线程名:"+Thread.currentThread().getName());
		new MyThread01().run();    //这样调用run只是普通方法,是主线程调用
	}
}

在这里插入图片描述
在这里插入图片描述

稍微复杂一点的例子

public class MyThread07 extends Thread{
	public MyThread07() {
		System.out.println("构造方法:"+Thread.currentThread().getName());
		System.out.println("构造方法:"+this.getName());
	}
	@Override
	public void run() {
		System.out.println("run:"+Thread.currentThread().getName());
		System.out.println("run:"+this.getName());
	}

	public static void main(String[] args) {
		MyThread07 myThread07 = new MyThread07();
		Thread thread=new Thread(myThread07);
		thread.setName("AAA");
		thread.start();
	}
}

在这里插入图片描述
结果分析:
首先,Thread.currentThread().getName()表示的是当前线程被谁调用,MyThread07对象是主线程创建的,所以是由主线程调用,结果是"main"。
run方法是由thread调用,thread的name是"AAA",所以Thread.currentThread().getName()打印的是"AAA",
两处this.getName是myThread07对象的name,默认是Thread-0。

猜你喜欢

转载自blog.csdn.net/fengsheng5210/article/details/85042158