在java中,每一个线程都是由Thread类对象创建和控制的。通常我们有两种方式来创建一个线程,一种是继承java.lang.Thread 类,第二种是创建类的时候实现Runnable接口。下面分别介绍两种方式。
1,继承Thread类
首先创建Thread子类的一个实例,然后重写run方法,然后子类的实例必须调用start()方法之后run方法才被执行. 代码如下:
public class MultiThread extends Thread {
public void run() {
System.out.println(getName()+"线程开始运行");
for(int i = 0; i< 10; i++) {
System.out.println(i +" "+getName());
try{
sleep((int) Math.random()*10);
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(getName() + "线程结束");
}
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName()+"线程开始运行");
new MultiThread().start();
System.out.println(Thread.currentThread().getName()+"线程结束");
}
}
2,实现Runnable接口
首先我们创建一个实现Runnable接口的类ThreadRunnable,为了让线程可以执行接口中的run()方法,我们要在Thread类的构造函数中传入ThreadRunnable的一个实例,这样线程就可以执行run方法。代码如下:
public class ThreadRunnable implements Runnable {
public int count = 0;
public void run() {
System.out.println("线程开始运行");
try {
while(count <3){
Thread.sleep(300);
count++;
}
}catch (InterruptedException e) {
System.out.println("线程终止");
}
System.out.println("线程结束");
}
public static void main(String[] args) {
ThreadRunnable instance = new ThreadRunnable();
Thread thread = new Thread(instance);
thread.start();
}
}
当我们创建线程的时候,我们一般倾向于实现一个Runnable接口。因为java中不支持多重继承,如果我们继承了Thread类,那这个类就不能继承其他的类了,而如果我们实现了Runnable接口我们还可以继承其它的类。有些时候我们可能仅仅需要让线程运行就可以,当我们继承了Thread类,我们却继承了Thread类所有的方法,过于浪费。
上面简单介绍了java中如何创建线程,下面讨论一下多线程的问题。
在同一程序中运行多个线程本身不会导致问题,但如果多个线程同时访问并修改了相同的资源,就会导致问题。值得我们注意的是,这些问题只有在多个线程向这些资源做了写操作时才有可能发生,多个线程读取相同的资源就是安全的。
下面我们举个例子:
public class ThreadAdd {
public static void main(String[] args) {
MyThread instence = new MyThread();
Thread thread0 = new Thread(instence);
Thread thread1 = new Thread(instence);
thread0.start();
thread1.start();
}
}
class MyThread implements Runnable {
private int sum = 0;
public void run() {
{
if(Thread.currentThread().getName().equals("Thread-0")){
sum += 2;
}else if(Thread.currentThread().getName().equals("Thread-1"))
sum += 3;
System.out.println(sum);
}
}
}
上面的代码中thread0 和thread1执行同一个MyThread对象的方法,我们期望sum最后的结果为5,但事实上sum可能为 2,3,5。导致这个结果的原因时线程在程序中是交错执行的。当两个线程竞争同一个资源时,如果对资源的访问顺序敏感,就出现了这种情况,我们称它为竞态条件,导致竞态条件的方法称为临界区,为了避免这种情况,我们往往在临界区中使用相应的同步机制。常用的有Synchronized,Mutex, Lock和Semaphore。
对于上面的例子我们可以任意选择一种同步机制,例如使用synchronized:
public void run() {
synchronized(this){
if(Thread.currentThread().getName().equals("Thread-0")){
sum += 2;
}else if(Thread.currentThread().getName().equals("Thread-1"))
sum += 3;
System.out.println(sum);
}
}
这样就可以保证sum的最终结果为5。
对于同步锁还有信号量的问题在其他文章里详细介绍。
分享到:
相关推荐
java中线程同步方法的总结,描述的很详细。
java线程同步java线程同步java线程同步
java多线程同步互斥访问实例,对于初学者或是温故而知新的同道中人都是一个很好的学习资料
java核心技术-多线程的概念及多线程单例设计模式的应用-懒汉模式、饿汉模式、优化懒汉
Java多线程同步论文.doc
java 多线程同步方法的实例 java 多线程同步方法的实例 java 多线程同步方法的实例
java多线程同步分析java多线程同步分java多线程同步分析析java多线程同步分析java多线程同步分析
Java多线程同步.pdf
Java多线程同步具体实例.doc
多线程注意:wait()方法的调用要有判定条件常用 while () obj.wait(timeout, nanos); ... // Perform action appropriate to condition } synchronized会影响共享数据,但对其他语句的执行不会有规律了!
Java线程(二):线程同步synchronized和volatile 详细讲解Java 同步的原理技术资料
当使用多个线程来访问同一个数据时,非常容易出现线程安全问题,所以我们用同步机制来解决这些问题,本文将详细介绍,需要的朋友可以参考下
Java多线程同步具体实例讲解 .doc
Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 ...
java线程同步实例,哲学家思考的代码实现,应该是一个比较好的例子
Java线程:线程的同步-同步方法 Java线程:线程的同步-同步块 Java线程:并发协作-生产者消费者模型 Java线程:并发协作-死锁 Java线程:volatile关键字 Java线程:新特征-线程池 Java线程:新特征-有返回值的...
JAVA代码采用线程来实现数据库的主从同步更新
一个详细讲解JAVA_线程同步与死锁的例子 希望可以帮助到你。