• 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  }

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


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

  • 相关阅读:
    tp5后台开发某些心得
    some note
    py数据抓取小案例(博客
    vue axios的使用
    C# WebApi POST 提交
    WebApi 返回Json
    C# WebApi 处理Area路径问题
    时间比较
    将多行数据合并为一列
    汉字转换拼音
  • 原文地址:https://www.cnblogs.com/FrenziedBug/p/3377899.html
Copyright © 2020-2023  润新知