Java多线程及同步实现原理

一. 实现多线程

1. 虚假的多线程

例1:

public class TestThread
{
  int i=0, j=0;
  public void go(int flag)
  {
   while(true)
   {
    try{ Thread.sleep(100);
   }
   catch(InterruptedException e)
   {
    System.out.println("Interrupted");
   }
   if(flag==0) i++;
   System.out.println("i=" + i);
   }
   else
   {
    j++;
    System.out.println("j=" + j);
   }
  }
}
public static void main(String[] args)
{
  new TestThread().go(0);
  new TestThread().go(1);
}
}


上面程序的运行结果为:

i=1

i=2

i=3

。。。

结果将一直打印出I的值。我们的意图是当在while循环中调用sleep()时,另一个线程就将起动,打印出j的值,但结果却并不是这样。关于sleep()为什么不会出现我们预想的结果,在下面将讲到。

2. 实现多线程

通过继承class Thread或实现Runnable接口,我们可以实现多线程

2.1 通过继承class Thread实现多线程

class Thread中有两个最重要的函数run()和start()。

1) run()函数必须进行覆写,把要在多个线程中并行处理的代码放到这个函数中。

2) 虽然run()函数实现了多个线程的并行处理,但我们不能直接调用run()函数,而是通过调用start()函数来调用run()函数。在调用start()的时候,start()函数会首先进行与多线程相关的初始化(这也是为什么不能直接调用run()函数的原因),然后再调用run()函数。

例2:

public class TestThread extends Thread
{
  private static int threadCount = 0;
  private int threadNum = ++threadCount;
  private int i = 5;
  public void run()
  {
   while(true)
   {
    try
    {
     Thread.sleep(100); 
    }
    catch(InterruptedException e)
    {
     System.out.println("Interrupted");
    }
    System.out.println("Thread " + threadNum + " = " + i);
    if(--i==0) return;
   }
  }
  public static void main(String[] args)
  {
   for(int i=0; i<5; i++)
    new TestThread().start();
  }
}


运行结果为:

Thread 1 = 5

Thread 2 = 5

Thread 3 = 5

Thread 4 = 5

Thread 5 = 5

Thread 1 = 4

Thread 2 = 4

Thread 3 = 4

Thread 4 = 4

Thread 1 = 3

Thread 2 = 3

Thread 5 = 4

Thread 3 = 3

Thread 4 = 3

Thread 1 = 2

Thread 2 = 2

Thread 5 = 3

Thread 3 = 2

Thread 4 = 2

Thread 1 = 1

Thread 2 = 1

Thread 5 = 2

Thread 3 = 1

Thread 4 = 1

Thread 5 = 1

从结果可见,例2能实现多线程的并行处理。

**:在上面的例子中,我们只用new产生Thread对象,并没有用reference来记录所产生的Thread对象。根据垃圾回收机制,当一个对象没有被reference引用时,它将被回收。但是垃圾回收机制对Thread对象“不成立”。因为每一个Thread都会进行注册动作,所以即使我们在产生Thread对象时没有指定一个reference指向这个对象,实际上也会在某个地方有个指向该对象的reference,所以垃圾回收器无法回收它们。

时间: 2025-01-20 11:00:34

Java多线程及同步实现原理的相关文章

Java多线程的同步示例及对象锁机制

java多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线程都打印从0到99这100个数字,我们希望线程之间不会出现交叉乱序打印,而是顺序地打印. 先来看第一段代码,这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这 是因为这里synchronized锁住的是this对象,即

数据同步-java多线程数据库同步问题

问题描述 java多线程数据库同步问题 从一个数据库抽取数据 放到自己数据库里面 中间回走数据处理 和判断 用java代码实现目前找到好的方法 多线程操作效率还是很低 一点思路没有 有这方面大神吗 解决方案 可以利用数据库之间的同步来做呀!简单又实用 http://jingyan.baidu.com/article/19192ad815ad0ee53e5707c9.html

java多线程的同步 通信以及生产消费者问题

Demo1 /*   Runable接口比直接从Thread继承方便的多  .  *    new  Thread(...) ;这样即使我们传递了同一个实现了Runnable接口的多个对象那么 也是多个线程 ,而且多个线程共享数据域. *    否则new Thread 创建的多个线程之间 互不相干  ,数据之间互不干涉 *    同步就是为了实现 在多个线程同时对一个资源进行操作的时候 要一个一个的执行 , *    只有等占有CPU的 线程完事之后 其他等待线程才能进入就绪状态等待运行 * 

学习Java多线程之同步_java

如果你的java基础较弱,或者不大了解java多线程请先看这篇文章<学习Java多线程之线程定义.状态和属性> 同步一直是java多线程的难点,在我们做android开发时也很少应用,但这并不是我们不熟悉同步的理由.希望这篇文章能使更多的人能够了解并且应用java的同步. 在多线程的应用中,两个或者两个以上的线程需要共享对同一个数据的存取.如果两个线程存取相同的对象,并且每一个线程都调用了修改该对象的方法,这种情况通常成为竞争条件. 竞争条件最容易理解的例子就是:比如火车卖票,火车票是一定的,

java多线程的同步与多线程锁介绍

线程的同步和锁的问题,我们先来看个例子, 下面的例子我们希望两个线程对m变量进行削减  代码如下 复制代码 packagecom.javaer.thread;  publicclassSysTestimplementsRunnable{ intm=10; publicstaticvoidmain(String[]args){ SysTests1=newSysTest(); Threadt1=newThread(s1,"Thread-t1"); Threadt2=newThread(s1

Java多线程的同步问题

这里我们在run()方法中加入了synchronized关键字,希望能对run方法进行互斥访问,但结果并不如我们希望那样,这是因为这里synchronized锁住的是this对象,即当前运行线程对象本身.代码中创建了10个线程,而每个线程都持有this对象的对象锁,这不能实现线程的同步.     代码     package com.vista;     class MyThread implements java.lang.Runnable {      private int threadI

Java多线程-线程的同步与锁的问题_java

一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. package cn.thread; public class Foo { private int x = 100; public int getX() { return x; } public int fix(int y) { x = x - y; return x; } } package cn.thread

java 多线程-下面两个方法同步吗,请说明理由,有什么方法可以验证?

问题描述 下面两个方法同步吗,请说明理由,有什么方法可以验证? class Test { synchronized static void say Hello3() { } synchronizedvoid getX() {} } 解决方案 现实应用如下场景: 一个人名叫王X的人 暗地销售火车票,数量为 SUM=1000; 某个时刻 用户甲从他那里购买了2张. 某个时刻 用户乙从他那里购买了4张. 某个时刻 用户丙从他那里购买了7张. ............... 购买者必须轮流购买火车票.

大量数据转录的多线程和同步处理实现

项目中需要对两个不同格式的存储设备进行数据转录,因为数据量非常大,所以时间非常缓慢:解决 方案是使用ReaderWriterSlim类建立一个共享的同步数据,可以支持一个线程读取外部设备,向同步数据 写入:多个线程从同步数据中读取,转换格式,然后写入到本地设备. 本例中采用Queue<T>作为存放数据的集合,写入线程向它的尾部写入对象,读取线程从它的头 部获取对象. 需要注意的是,由于Queue会抛弃已处理的对象,所以在同步数据队列中无法验证数据对象的唯一性, 被写入的数据库需要去掉唯一约束,