• (一道面试题)关于线程


    一.多线程的主要优点:提高效率 。但是存在线程安全,上代码:

    现实多线程的方法:实现Runnable接口,继承Thread类

    (一般是实现Runnable接口,主要原因是java不支持多重继承,一旦你继承了Thread类那么你就无法继承其他类,局限性太大了)

    一.多线程的实现

    1.这里我是实现Runnable接口来实现多线程

    public class Producter implements Runnable {
        public static List<String> nlist=new LinkedList<String>();//存放产品  
        private Integer number;  //用来存放产品编号
        private String  productName;  //用来存放产品名称
    	/*
    	 * 实现Runnable接口,生产产品,并将其添加到容器中
    	 */
    	@Override
    	public  void run() {	
    			//定义产品编号,从1开始	
    			number=nlist.size()+1;
    			//定义产品的名字
    			productName=number+"号产品";
    			//将生产好的产品存放到容器中
    			nlist.add(productName);
    			// TODO Auto-generated method stub					
    	}
    }
    

    2.测试类,定义100个线程来测试多线程时发生的问题

    public class TestDemo {
         public static void main(String[] args) throws InterruptedException {
            //生产100个产品
        	for(int i=0;i<100;i++){
    		Thread thread=new Thread(new Producter());
    		thread.start();
        	 }   	
            //等待3s因为主线程跟线程是并行进行的.不等待返回的nlist的值不确定.  	
        	Thread.sleep(3000);
        	//遍历打印出的容器的产品
        	for(String s:Producter.nlist)
        	{
        		System.out.println(s);
        	}
    	}
    }
    

    3.实验结果:

    4.分析结果:

    这是因为有多个线程同时访问了run()方法.造成了一个产品被多次制造。

    二.多线程安全问题的解决:加锁(synchronized关键字)

    给run()方法加锁.----目的: 当对象访问run()时只允许最多一个线程访问.这个就可以解决一个产品被多次制造的问题了.

    1.修改Producter方法

    public class Producter implements Runnable {
        public static List<String> nlist=new LinkedList<String>();//存放产品  
        private Integer number;  //用来存放产品编号
        private String  productName;  //用来存放产品名称
    	/*
    	 * 实现Runnable接口,生产产品,并将其添加到容器中
    	 */
    	@Override
    	public  void run() {
    		//加锁最多允许一个线程进来
    		synchronized (this.getClass()) {
    			//定义产品编号,从1开始	
    			number=nlist.size()+1;
    			//定义产品的名字
    			productName=number+"号产品";
    			//将生产好的产品存放到容器中
    			nlist.add(productName);
    			// TODO Auto-generated method stub		
    		}
    						
    	}
    }
    

    2.为了容易观看修改了测试类代码(每打印10个换行):

    public class TestDemo {
        private static int count=0;
         public static void main(String[] args) throws InterruptedException {
            //生产100个产品
            for(int i=0;i<100;i++){
            Thread thread=new Thread(new Producter());
            thread.start();
             }       
            //等待3s因为主线程跟线程是并行进行的.不等待返回的nlist的值不确定.      
            Thread.sleep(3000);
            //遍历打印出的容器的产品
            for(String s:Producter.nlist)
            {
                //每10次换行
                count++;
                System.out.print(s);
                if(count%10==0)
                {
                    System.out.println();
                }
            }
        }
    }

    3.实验结果(没有一个重复的):

     4.总结

    在实现多线程时必须考虑到线程安全问题,不然会有许多的意外结果(BUG)~

  • 相关阅读:
    jenkins无法显示html样式问题解决
    自定的 HttpModule 为什么总是执行两次
    符号服务器
    ThreadContext
    ThreadContext
    从代码看 asp.net 处理过程
    关于动态编译
    System.Web.HttpContext.Current 跟踪分析
    使用另一种方式实现会话功能
    for 与 foreach 性能
  • 原文地址:https://www.cnblogs.com/hckblogs/p/7844549.html
Copyright © 2020-2023  润新知