首页 > 代码库 > java线程

java线程

1、进程(Process),线程(Thread)区别
  进程每个独立执行的程序称为进程。

  线程线程是一个程序内部的一条执行路径。

  1. 进程:进程是一个静态的概念
  2. 线程:一个进程里面有一个主线程叫main()方法,是一个程序里面的,一个进程里面不同的执行路径。
  3. 在同一个时间点上,一个CPU只能支持一个线程在执行。因为CPU运行的速度很快,因此我们看起来的感觉就像是多线程一样。

2、创建新线程两种方法:
   (1)继承Thread类 重写run()方法
   启动方法:TikectThread tikectThread = new TikectThread(),
            tikectThread.start()
(2)定义"Runnable"接口的实现类
  与实现Thread类的线程启动方法不同:
  (1)首先创建此线程类的实例:TikectThread tikectThread = new TikectThread()
  (2)把线程类实例作为参数传递给线程实例:Thread thread1 = new Thread(tikectThread)

(3)启动:线程再启动的时候是调用 start()方法,而不是run()方法


4、线程的五个状态:
  (1)创建
  (2)就绪
  (3)运行
  (4)阻塞
  (5)终止

5、线程的方法:
  (1)public void start()启动线程
  (2)public static Thread currentThread()// Thread currentThread()返回当前正在执行的线程的引用对象
  (3)public ClassLoader getContextClassLoader()// getContextClassLoader()返回该线程的上下文 ClassLoader
  (4)public final boolean isAlive()// isAlive测试线程是否处于激活状态
  (5)Thread.state getState()// 返回线程状态
  (6)public final String getName()// 返回线程名称
  (7)public final void setName(String name)// 设置线程名称
  (8)public final void setDaemon(boolean on)// 将该线程标记为守护线程或用户线程

6、线程调度:

  线程睡眠
  (1)public static void yield()暂停当前正在执行的线程对象,并执行其他线程
  线程让步
  (2)public static void sleep(long millis) throws InterruptedException
    在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权
  线程加入

  (3)join() throws InterruptedException 方法 在当前线程中调用另一个线程的 join()方法,则当前线程转入WAITING状态,直到另一个线程运行结束,当前线程再由阻塞转为就绪状态

  下边的线程等待、唤醒方法只能在被同步化(synchronized)的方法或代码块中调用

  线程等待

  (4)Object 类中的wait() throws InterruptedException 方法,导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 唤醒方法。

   线程唤醒

  (5) Object 类中的notify()方法,唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的。 Object类中的notifyAll()方法,唤醒在此对象监视器上等待的所有线程

几个示例:

线程礼让 

1
public class TestThreadYield { 2 public static void main(String[] args) { 3 System.out.println("主线程:" + Thread.currentThread().getName()); 4 Thread thread1 = new Thread(new MyThread2()); 5 thread1.start(); 6 Thread thread2 = new Thread(new MyThread2()); 7 thread2.start(); 8 } 9 }10 class MyThread2 implements Runnable{11 public void run() {12 for(int i = 0; i < 100; i++){13 System.out.println(Thread.currentThread().getName()+ ":" + i);14 if(i % 10 == 0){ Thread.yield(); //线程让步 }15 }16 }17 }
线程合并

1
public class TestThreadJoin { 2 public static void main(String[] args) { 3 Thread thread1 = new Thread(new MyThread3()); 4 thread1.start(); 5 for (int i = 1; i <= 100; i++) { 6 System.out.println(Thread.currentThread().getName() + ":" + i); 7 if (i == 50) { 8 try { thread1.join(); //线程合并 9 } catch (InterruptedException e) { e.printStackTrace(); }10 }11 }12 }13 }14 class MyThread3 implements Runnable{15 public void run() {16 for (int i = 1; i <= 50; i++) {17 System.out.println(Thread.currentThread().getName() + ":" + i);18 try { Thread.sleep(100); 19 } catch (InterruptedException e) { e.printStackTrace(); }20 }21 }22 }

 


7、线程优先级:setPriority()、getPriority()
  Thread 类有以下三个静态常量:
    .static int MIN_PRIORITY 线程可以具有的最低优先级,取值为 1
    .static int NORM_PRIORITY 分配给线程的默认优先级,取值为 5
    .static int MAX_PRIORITY 线程可以具有的最高优先级,取值为 10

8、多线程安全问题
  当run()方法体内的代码操作到了成员变量(共享数据)时,就可能会出现多线程安全问题(线程不同步问题)

编程技巧:
  在方法中尽量少操作成员变量,多使用局部变量

9、线程的同步:
  (1)在Java语言中,引入对象互斥锁的概念,保证共享数据操作的完整性。每个对象都对应于一个可称为“互斥锁”的标记,这个标记保证在任一时刻,只能有一个线程访问对象
  (2)关键字synchronized用来与对象的互斥锁联系。当某个对象用synchronized修饰时,表明该对象在任一时刻只能由一个线程访问。
  (3)一个方法使用关键字synchronized修饰后,当一个线程A使用这个方法时,其他线程想使用这个方法就必须等待,直到线程A使用完该方法
    synchronized放在对象前面限制一段代码的执行
    synchronized(this){需要同步的代码;}
    synchronized放在方法声明中,表示整个方法为同步方法:
      public synchronized void sale()

10、线程死锁
  死锁的原因:线程1锁住资源A等待资源B,线程2锁住资源B等待资源A,两个线程都在等待自己需要的资源,而这些资源被另外的线程锁住,这些线程你等我,我等你,谁也不愿意让出资源,这样死锁就产生了
  解决死锁的办法:加大锁的粒度

11、理解线程的等待和唤醒

  技术分享

12、多线程编程的一般规则 

  (1)如果两个或两个以上的线程都修改一个对象,那么把执行修改的方法定义为被同步的,如果对象更新影响到只读方法,那么只读方法也要定义成同步的.

  (2)不要滥用同步。如果在一个对象内的不同的方法访问的不是同一个数据,就不要将方法设置为synchronized的.

  (3)如果一个线程必须等待一个对象状态发生变化,那么他应该在对象内部等待,而不是在外部。他可以通过调用一个被同步的方法,并让这个方法调用wait().

  (4)每当一个方法返回某个对象的锁时,它应当调用notifyAll()来让等待队列中的其他线程有机会执行.

  (5)记住wait()和notify()/notifyAll()是Object类方法,而不是Thread类的方法。仔细查看每次调用wait()方法,都有相应的notify()/notifyAll()方法,且它们均作用于同一个对象.

java线程