Java当中的线程(三)

这一章说的是线程的同步问题

先来个例子

MyThread.java

class MyThread implements Runnable{
	int i = 100;
	public void run(){
		while(true){
			//Thread.currentThread(),代表当前运行的线程
			System.out.println(Thread.currentThread().getName() + i);
			i --;
			//使当前运行的线程让出CPU,再次就绪。
			Thread.yield();
			if(i < 0){
				break;
			}
		}
	}
}

Test.java

class Test{
	public static void main(String args []){
		
		MyThread myThread = new MyThread();
		//生成两个Thread对象,但是两个Thread对象共用同一个线程体
		Thread t1 = new Thread(myThread);
		Thread t2 = new Thread(myThread);
		//每一个线程都有名字,可以通过Thread对象的setName()方法设置线程名字,
		//也可以使用getName()方法获取线程的名字。
		t1.setName("线程a");
		t2.setName("线程b");
		//分别启动两个线程
		t1.start();
		t2.start();
	}
}

运行部分结果如下图:


从上面的结果看到,线程b1和线程a1,没有3,没有0,显然,线程出错了

线程a在执行完输出线程a1之后,轮到线程b1执行,两线程都有自己的线程体,这时就是
两个线程都打印了一次1.所以,这个是线程操作不对,也是线程抢占的无规律性产生的数据访问安全问题。

这里介绍同步代码块
MyThread.java
class MyThread implements Runnable{
	int i = 100;
	public void run(){
		while(true){
			synchronized(this){
				//Thread.currentThread(),代表当前运行的线程
				System.out.println(Thread.currentThread().getName() + i);
				i --;
				//使当前运行的线程让出CPU,再次就绪。
				Thread.yield();
				if(i < 0){
					break;
				}
			}	
		}
	}
}

synchronized相当于同步锁,线程运行同步锁,就相当于拿了钥匙,可以执行下面的代码,而其他线程就要等待,等待这个线程运行完所有代码,
即使这个线程运行了代码的一半后,被其他线程抢占了,但是其他线程没有得到这个同步锁,也只能等待,直到这个线程运行完所有代码,释放出同步锁。
这就保护了数据的安全性。
编译运行就可以发现 ,刚刚的重复数字没有了,但是最后却有一个-1.   可能是因为两线程,一个线程break了,还有一个线程没有break。下面代码测试一下
MyThread.java
class MyThread implements Runnable{
	int i = 100;
	public void run(){
		while(true){
			synchronized(this){
				//Thread.currentThread(),代表当前运行的线程
				System.out.println(Thread.currentThread().getName() + i);
				i --;
				//使当前运行的线程让出CPU,再次就绪。
				Thread.yield();
				if(i < 0){
					System.out.println(Thread.currentThread().getName() + "out");
					break;
				}
			}	
		}
	}
}

在break的前面加一句打印语句,把break的线程名+out打印出来。下面编译运行看结果。只看最后一段



显然,0的时候,线程b就break了,但是线程a还在运行,运行打印-1后,线程a也break了。程序停了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值