练习题:卖100个苹果java多线程数据同步,实现数据共享。
新建一个线程有两种方式:1.继承类;2.是实现的方式:
那我们就先使用第一种方式来实现:
使用实现数据的共享 第一步:
写一个了继承java多线程数据同步,并在定义一个静态的变量(注意:因为是静态的java多线程数据同步-java多线程实现数据共享,所以是共享数据)
<pre class="prettyprint">` /**
* 存在数据共享
* @author liujun
*
*/
class ShareThread extends Thread{
private static int Apple_Counts=100;//共享数据-苹果个数
@Override
public void run() {
while(Apple_Counts>0){
if (Apple_Counts>0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}`</pre>
在main方法开始三个线程:
<pre class="prettyprint">` ShareThread mShareThread1=new ShareThread();
ShareThread mShareThread2=new ShareThread();
ShareThread mShareThread3=new ShareThread();
mShareThread1.start();
mShareThread2.start();
mShareThread3.start();`</pre>
执行的结果:
Thread-0卖了一个苹果,还剩99
Thread-1卖了一个苹果,还剩98
Thread-2卖了一个苹果,还剩99
Thread-0卖了一个苹果,还剩97//这里数据出现有错,因为上面的线程里没有使用同步锁
Thread-1卖了一个苹果,还剩97
........................
........................
Thread-0卖了一个苹果,还剩2
Thread-2卖了一个苹果,还剩1
Thread-1卖了一个苹果,还剩0
Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁
Thread-2卖了一个苹果,还剩-2
第二步:
给中添加同步代码块:
<pre class="prettyprint">` /**
* 存在数据共享
* @author liujun
*
*/
class ShareThread extends Thread{
private static int Apple_Counts=100;//共享数据-苹果个数
@Override
public void run() {
while(Apple_Counts>0){
//注意这里添加了同步代码块,同步锁对象是this
synchronized (this) {
if (Apple_Counts>0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}`</pre>
再次执行main方法打印的结果:
Thread-2卖了一个苹果,还剩98
Thread-1卖了一个苹果,还剩99
Thread-0卖了一个苹果,还剩97
Thread-1卖了一个苹果,还剩96
Thread-0卖了一个苹果,还剩95
........................
........................
Thread-0卖了一个苹果,还剩1
Thread-1卖了一个苹果,还剩0
Thread-2卖了一个苹果,还剩0 //这里数据出现有错,都使用同步锁了?为什么????????
Thread-0卖了一个苹果,还剩-1
第三步:
分析代码:
多线程在使用的时候,多个线程使用的锁对象必须是同一个。
<pre class="prettyprint">` ShareThread mShareThread1=new ShareThread();
ShareThread mShareThread2=new ShareThread();
ShareThread mShareThread3=new ShareThread();`</pre>
上面这三行代码new了三个对象,那么上面使用的同步锁是this;那上面的多线程在使用的时候,多个线程使用的锁对象(this)不是同一个,它们是分别为,,。所以上面虽然使用了还是会出现数据有错。
第四步:
修改代码:
保证使多线程在使用的时候,多个线程使用的锁对象是同一个就行,下面使用了的同步锁对象是:.class。
<pre class="prettyprint">` /**
* 存在数据共享
* @author liujun
*
*/
class ShareThread extends Thread{
private static int Apple_Counts=100;//共享数据-苹果个数
@Override
public void run() {
while(Apple_Counts>0){
//注意这里添加了同步代码块,同步锁对象是ShareThread.class
synchronized (ShareThread.class) {
if (Apple_Counts>0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}`</pre>
再次执行main方法打印的结果正常:
Thread-2卖了一个苹果,还剩98
Thread-1卖了一个苹果,还剩99
Thread-0卖了一个苹果,还剩97
Thread-1卖了一个苹果,还剩96
Thread-0卖了一个苹果,还剩95
........................
........................
Thread-0卖了一个苹果,还剩1
Thread-1卖了一个苹果,还剩0
总结:
1.上面通过继承类的方式已经实现数据共享,但是一般我们不定义静态的变量作为数据共享,因为静态的生命周期比较长。
2.建议实现数据共享时使用实现来实现。
使用实现数据的共享 第一步:
写一个了实现,并在定义一个变量(注意:是共享数据)
<pre class="prettyprint">`
/**
* 存在数据共享
* @author liujun
*
*/
class ShareRunable implements Runnable{
private int Apple_Counts=100;//Apple_Counts就是共享数据
@Override
public void run() {
while(Apple_Counts>0){
if(Apple_Counts>0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}`</pre>
在main方法开始三个线程:
<pre class="prettyprint">` ShareRunable mMyRunables=new ShareRunable();
new Thread(mMyRunables).start();
new Thread(mMyRunables).start();
new Thread(mMyRunables).start();`</pre>
执行的结果:
Thread-0卖了一个苹果,还剩99
Thread-1卖了一个苹果,还剩98
Thread-2卖了一个苹果,还剩99
........................
........................
Thread-0卖了一个苹果,还剩2
Thread-2卖了一个苹果,还剩1
Thread-1卖了一个苹果,还剩0
Thread-0卖了一个苹果,还剩-1 //这里数据出现有错,因为上面的线程里没有使用同步锁
Thread-2卖了一个苹果,还剩-2
第二步:
给中添加同步代码块:
<pre class="prettyprint">` /**
* 存在数据共享
* @author liujun
*
*/
class ShareRunable implements Runnable{
private int Apple_Counts=100;//Apple_Counts就是共享数据
@Override
public void run() {
while(Apple_Counts>0){
//注意这里添加了同步代码块,同步锁对象是this或者是ShareThread.class
synchronized (this) {
if(Apple_Counts>0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"卖了一个苹果,还剩"+--Apple_Counts);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}`</pre>
再次执行main方法打印的结果正常:
Thread-2卖了一个苹果,还剩99
Thread-1卖了一个苹果,还剩98
Thread-0卖了一个苹果,还剩97
Thread-1卖了一个苹果,还剩96
Thread-0卖了一个苹果,还剩95
........................
........................
Thread-0卖了一个苹果,还剩1
Thread-1卖了一个苹果,还剩0
总结:
1.上面通过实现类的方式已经实现数据共享
2.建议实现数据共享时使用实现来实现。
文章来源:https://blog.csdn.net/u012987546/article/details/52140164