java多线程实战( 多个线程 修改同一个变量)
来源:互联网 发布:淘宝放心淘是什么 编辑:程序博客网 时间:2024/05/20 05:56
java多线程实战( 多个线程 修改同一个变量) synchronized 同步
介绍
java多线程实战
需求
创建两个线程,分别输出“a”,“b”,要求输出总和为30个。
线程介绍
一、定义线程
1、扩展java.lang.Thread类。
此类中有个run()方法,应该注意其用法:
public void run()
如果该线程是使用独立的Runnable
运行对象构造的,则调用该Runnable
对象的run
方法;否则,该方法不执行任何操作并返回。Thread
的子类应该重写该方法。
2、实现java.lang.Runnable接口。
void run()
使用实现接口Runnable
的对象创建一个线程时,启动该线程将导致在独立执行的线程中调用对象的run
方法。
方法run
的常规协定是,它可能执行任何所需的操作。
二、实例化线程
1、如果是扩展java.lang.Thread类的线程,则直接new即可。
2、如果是实现了java.lang.Runnable接口的类,则用Thread的构造方法:
Thread(Runnable target)
Thread(Runnable target, String name)
Thread(ThreadGroup group, Runnable target)
Thread(ThreadGroup group, Runnable target, String name)
Thread(ThreadGroup group, Runnable target, String name, long stackSize)
三、启动线程
在线程的Thread对象上调用start()方法,而不是run()或者别的方法。
在调用start()方法之前:线程处于新状态中,新状态指有一个Thread对象,但还没有一个真正的线程。
在调用start()方法之后:发生了一系列复杂的事情
启动新的执行线程(具有新的调用栈);
该线程从新状态转移到可运行状态;
当该线程获得机会执行时,其目标run()方法将运行。
注意:对Java来说,run()方法没有任何特别之处。像main()方法一样,它只是新线程知道调用的方法名称(和签名)。因此,在Runnable上或者Thread上调用run方法是合法的。但并不启动新的线程。
功能实现
package com.thread;public class ThreadTest {public int i=0;//计数器public static final int MAX=30;//总次数public static void main(String args[]){ThreadTest t = new ThreadTest();Thread thread1 = new Thread(new MeThead(t,0));Thread thread2 = new Thread(new MeThead(t,1));thread1.start();thread2.start();}/** * 需要考虑变量i的同步问题。 * @return */public <span style="color:#ff6666;">synchronized</span> boolean printA(){if(i<MAX){System.out.print(i+"a");i++;return true;}return false;}/** * 需要考虑变量i的同步问题。 * @return */public <span style="color:#ff6666;">synchronized</span> boolean printB(){if(i<MAX){System.out.print(i+"b");i++;return true;}return false;}}class MeThead implements Runnable{ThreadTest t;int method=0;public MeThead(ThreadTest t,int method){this.t=t;this.method=method;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(1==1){boolean flag =false;if(method==0){flag = t.printA();}else if(method==1){flag = t.printB();}//如果结束了,则退出循环if(flag==false){break;}}}}
注意点:
1.需要考虑同一个变量的同步的问题!对同一个变量的操作,必须要放入到同步方法内。否则取到的变量值会不一致!
举个例子,如果thread里面的run方法是如下实现,则就会出现变量的值不一致问题!
比如第一次,i=0,那么thread1和thread2同时进入了while循环内,thread1执行了printA方法,thread2则等待thread1释放资源。可能thread1执行了30次,最后i=30之后thread1执行完成。这时候,thread2还在等待中,发现资源已经可以使用了,则调用了printB的方法。最后就会出现打印了31次的情况!
这个需要注意的。不然很容易搞错。
如下是错误的程序:
<span style="color:#333333;"></span>package com.thread;public class ThreadTest {<span style="white-space:pre"></span>public static void main(String args[])<span style="white-space:pre"></span>{<span style="white-space:pre"></span>ThreadTest t = new ThreadTest();<span style="white-space:pre"></span>Thread thread1 = new Thread(new MeThead(t,0));<span style="white-space:pre"></span>Thread thread2 = new Thread(new MeThead(t,1));<span style="white-space:pre"></span>thread1.start();<span style="white-space:pre"></span>thread2.start();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public synchronized void printA()<span style="white-space:pre"></span>{<span style="white-space:pre"></span>System.out.print(Param.i+"a");<span style="white-space:pre"></span>Param.i++;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public synchronized void printB()<span style="white-space:pre"></span>{<span style="white-space:pre"></span>System.out.print(Param.i+"b");<span style="white-space:pre"></span>Param.i++;<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>}/** * 设置成全局静态变量。 * @author hbx * */class Param{<span style="white-space:pre"></span>public static int i=0;//两个线程每打印一次,i进行自增一次,跟MAX比较,只要小于MAX,则一直打印<span style="white-space:pre"></span>public static final int MAX=20;<span style="white-space:pre"></span>}class MeThead implements Runnable{<span style="white-space:pre"></span>ThreadTest t;<span style="white-space:pre"></span>int method=0;<span style="white-space:pre"></span>public MeThead(ThreadTest t,int method)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>this.t=t;<span style="white-space:pre"></span>this.method=method;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void run() {<span style="white-space:pre"></span>// TODO Auto-generated method stub<span style="white-space:pre"></span><span style="white-space:pre"></span><span style="color:#ff6666;">while(Param.i<Param.MAX)</span><span style="white-space:pre"></span>{<span style="white-space:pre"></span><span style="white-space:pre"></span>if(method==0)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>//System.out.println("-"+Param.i+"a-");<span style="white-space:pre"></span><span style="color:#ff6666;">t.printA();</span><span style="white-space:pre"></span>}<span style="white-space:pre"></span>else if(method==1)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>//System.out.println("-"+Param.i+"b-");<span style="white-space:pre"></span><span style="color:#ff6666;">t.printB()</span>;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>}<span style="white-space:pre"></span><span style="white-space:pre"></span>}<span style="color:#333333;"></span>
0 0
- java多线程实战( 多个线程 修改同一个变量)
- java 多线程操作同一个变量
- 多个线程调用同一个线程函数
- 多线程操作同一个变量
- java实现4个线程对一个公共变量修改
- 多个线程访问同一个类里面的静态成员变量
- 多个函数使用同一个变量
- 多线程用同一个dao对象就会存在多个线程执行同一方法,为什么不用考虑线程安全问题
- 多个线程调用同一个线程函数的方法
- java中,多个线程同时调用同一个静态方法的问题
- java针对一个资源,创建多个线程来处理同一个事件
- java线程实战:多线程下载(上)
- java线程实战:多线程下载(下)
- java,同一个Runnable对象扔线程池多次和多个实例对象扔线程池有啥不同啊?
- Java多线程探究-线程局部变量ThreadLocal
- 多个线程如何操作同一个epoll fd
- 多个线程如何操作同一个epoll fd
- 多个线程如何操作同一个epoll fd
- C#常见编译错误
- CodeForces 398B 概率DP 记忆化搜索
- android 工具类篇 ResourceUtils
- USACO Friday the Thirteenth
- C#程序将DLL包进EXE方法
- java多线程实战( 多个线程 修改同一个变量)
- Java中的接口
- 【人生成就达成】【#1】
- Kaldi安装实录(二)
- Android ContentProvider Cursor
- 我所知道的Ribbon库
- unrecognized selector sent to instance出现的原因和解决方案
- 机器学习-百度笔试题
- 从设计层面看abstract class和interface