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

    java多线程

    线程的概念就不赘述了,有几个需要注意的点:

    1.static pubic void main(String[] args)这就是程序的主线程,它也是一个线程。

    2.java中有两个实现多线程的方式继承Thread方法,implements Runnable接口。

    3.多线程应用中的多种功能:大致如下图(盗的图~)

    先贴上一个最简单的多线程的例子:

    import java.lang.Thread;
    
    public class Main {
    
        static public void main(String[] arg) {
            BaseThread baseThread = new BaseThread();
            new Thread(baseThread, "A").start();
            new Thread(baseThread, "B").start();
        }
    }
    
    
    
    
    public class BaseThread implements Runnable{
        
        public void run(){
            for(int i=0; i<5; i++){
                System.out.println(Thread.currentThread().getName()+"  "+i);
            }
        }
    }

    结果:

    B  0
    A  0
    B  1
    A  1
    B  2
    A  2
    B  3
    A  3
    B  4
    A  4
    

    这个大概能反应效果,但是好像有点有规律,不要在意这些细节。

    线程的实现:cup是分时处理指令的,就是说在一个时钟周期内处理一条指令,那么现在我开启两个线程,cpu就会一会儿执行线程A的指令,一会儿执行线程B的指令,看起来好像是A和B同时在执行一样,其实cpu内部还是一个异步执行机制。

    那么如果按照上面这种情况就会出现一个问题,我们之前在代码中苦心经营的时间上的逻辑关系在这里就会变得相当难搞了,举一个例子:

    现有一个订票的网站,有A,B两个用户,现在只剩一张票,现在A买了一张票,票数减一等于零了,但是现实当前票数的代码还没有变化还是1,然后执行B,B看到还剩一张点击购买,怎么办?如何解决这种问题。有逻辑性的代码执行不同步的后果。这时就需要用到图中提供的那么多API来实现这些功能了。哦,还有就是多线程的指令执行控制,是系统决定的,不是我们所能掌握的,我们只能通过这些API去管理使用。

    线程的生命周期

    线程同步和死锁 举个订票的简单例子:

     1 public class BaseThread implements Runnable{
     2     
     3     public void run(){
     4         for(int i=0; i<10; i++){
     5             if(count>0){
     6                 try{
     7                     Thread.sleep(1000);
     8                 }catch(InterruptedException e){
     9                     System.out.println(e.getStackTrace());
    10                 }
    11                 count--;
    12                 System.out.println(count);
    13             }
    14         }
    15     }
    16     
    17     static public void main(String[] arg) throws InterruptedException {
    18         BaseThread baseThread = new BaseThread();
    19         Thread h1 = new Thread(baseThread,"h1");
    20         Thread h2 = new Thread(baseThread,"h2");
    21         h1.setPriority(1);
    22         h2.setPriority(5);
    23         h1.start();
    24         h2.start();
    25     }
    26     private int count = 5;
    27 }

    测试时会有这种输出

    3
    3
    2
    1
    0
    -1

    出现这种结果的原因:假如现在count=1,然后A线程访问了,count>1,这时B线程也访问了,count>1,然后这时这两个线程就都进入了if,然后就对count进行了--操作。所以出现了这种情况。

    这时可以通过线程同步的方法解决这个问题,用synchronized  这时同步关键字,它能保证一个时间内只有一个线程访问。例如上面代码可以变成这样:

    public class BaseThread implements Runnable {
    
    	public void run() {
    		for (int i = 0; i < 10; i++) {
    			synchronized (this) {
    				if (count > 0) {
    					try {
    						Thread.sleep(1000);
    					} catch (InterruptedException e) {
    						System.out.println(e.getStackTrace());
    					}
    					count--;
    					System.out.println(count);
    				}
    			}
    		}
    	}
    
    	static public void main(String[] arg) throws InterruptedException {
    		BaseThread baseThread = new BaseThread();
    		Thread h1 = new Thread(baseThread, "h1");
    		Thread h2 = new Thread(baseThread, "h2");
    		h1.setPriority(1);
    		h2.setPriority(5);
    		h1.start();
    		h2.start();
    	}
    
    	private int count = 5;
    }
    

    synchronized (对象){}然后把要同步的代码放进{}内就可以了,对象就是要屏蔽的对象,这个里面就是this。

    关于synchronized我最近看到一个关于它功能的说明比较好的:

    http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html(下面说明的来源)

    一、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

    二、然而,当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

    三、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

    四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。

    五、以上规则对其它对象锁同样适用.

     这里有一点值得注意,

    还有好多东西:

    多线程与单例:http://www.cnblogs.com/zxh1210603696/p/4157294.html(单例与多线程)

    notify 和 wait :http://www.cnblogs.com/mengdd/archive/2013/02/20/2917956.html  (多线程通信wait和notify) http://www.cnblogs.com/gw811/archive/2012/10/17/2727266.html(依然是线程的同步synchronize)。

  • 相关阅读:
    数据绑定控件的上下文Container dodo
    jquery的调试利器:Firebug使用详解 dodo
    Scrum中的角色 dodo
    jquery easyui datagrid的增加,修改,删除 dodo
    计划扑克(Planning Poker) dodo
    windows2003 IIS 服务启动失败,提示‘另一个程序正在使用此文件,进程无法访问',解决方法 dodo
    控件包含代码块(即 <% ... %>),因此无法修改控件集合 dodo
    AppendFormat System.FormatException: 输入字符串的格式不正确 dodo
    Scrum中的燃烧曲线(Burndown Chart) dodo
    在类中获取、使用当前页面 Page 对象的引用 dodo
  • 原文地址:https://www.cnblogs.com/chaiwentao/p/4138974.html
Copyright © 2011-2022 走看看