zoukankan      html  css  js  c++  java
  • java 多线程学习笔记

    这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解。


    一:实现多线程的两种方法

    1.继承Thread

    1 class MyThread1 extends Thread{
    2     public void run(){
    3         System.out.println("这是自定义的线程");
    4     }
    5 }

    通过继承Thread,然后重写Thread中的run方法,把自己要实现的方法写在run()中

    1  class ThreadTest1{
    2      public static void main(String[] args){
    3          MyThread1 mythread = new MyThread1();
    4          mythread.start();
    5      }
    6  }    

    2.实现Runnable接口

    1  class MyThread implements Runnable{
    2      public void run(){
    3          System.out.println("这是自定义的实现Runnable接口的线程");
    4      }
    5  }

    实现Runnable接口,然后实现它的方法run

    1 class ThreadTest1{
    2     public static void main(String[] args){
    3         MyThread mythread = new MyThread();
    4         Thread thread = new Thread(mythread);
    5         thread.start();
    6     }
    7 }

    把mythread传到Thread的构造方法中,然后就生成了一个线程。

    二:线程的安全性问题

     1  class MyThread implements Runnable{
     2       int i = 100;
     3       public void run(){
     4           while(true){
     5               System.out.print(Thread.currentThread().getName()+i+“ ”);
     6               Thread.yield();
     7               i--;
     8               if(i<0){
     9                   break;
    10               }
    11          }
    12      }
    13  }

     1 class ThreadTest{
     2     public static void main(String[] args){
     3         MyThread mythread = new MyThread();
     4         Thread thread = new Thread(mythread);
     5         Thread thread2 = new Thread(mythread);
     6         thread.setName("线程A");
     7         thread2.setName("线程B");
     8         thread.start();
     9         thread2.start();
    10     }
    11 }

    ThreadTest的main运行结果:

    线程A10 线程B10 线程A9 线程B8 线程A7 线程B6 线程A5 线程B4 线程A3 线程B2 线程B1 线程A0

    这结果是不是很奇怪,为什么有线程A10 线程B10 。要是这是一个火车售票系统,那么不是卖个两个人同一个火车票了么?

    也许这个例子过于简单,看不出什么,可以参考:http://www.blogjava.net/tscfengkui/archive/2010/11/10/337709.html?opt=admin

    原因主要是线程A运行run方法,运行到System.out.println(),但是还没有运行到i--,可是这是线程B抢占到了资源,那么线程B开始运行,然后线程B又运行到了System.out.println(),然后线程A或者B中有一个运行i--.然后A再运行println()。

    解决办法就是在线程运行run使用资源的时候交给他一把锁,等它把事情做完后在把锁给另一个要用这个资源的线程。这样就不会出现上述情况。 实现这个锁的功能就需要用到synchronized这个关键字。

    synchronized这个关键字有两种用法1、放方法名前形成同步方法;2、放在块前构成同步块。

    方法1:在方法名前形成同步方法

     1 class MyThread implements Runnable{
     2     int i = 10;
     3     public void run(){
     4          /* for(int i = 0; i <100; i++){
     5              //获得当前正在运行线程的名字
     6             System.out.println(Thread.currentThread().getName()+i);
     7         }  */
     8         this.meA();
     9         }
    10     public synchronized void meA(){
    11         while(true){
    12             System.out.print(Thread.currentThread().getName()+i+" ");
    13             Thread.yield();
    14             i--;
    15             if(i<=0){
    16                 break;
    17             }
    18         }
    19     }
    20 }

    运行结果

    线程A10 线程A9 线程A8 线程A7 线程A6 线程A5 线程A4 线程A3 线程A2 线程A1 线程B0

    方法二:放在块前构成同步块

    比如上面例子中,只要在while中加入一个方法块

     1  while(true){
     2         synchronized(this){
     3            System.out.print(Thread.currentThread().getName()+i+" ");
     4            Thread.yield();
     5            i--;
     6            if(i<0){
     7                break;
     8            }
     9       }
    10  }

    那么实现的结果和上面是一样的。


    这是我今天学习多线程的结果,多线程很深奥,越学越觉得好多还不懂,只能每天进步一点。

  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/FrenziedBug/p/3377899.html
Copyright © 2011-2022 走看看