zoukankan      html  css  js  c++  java
  • Java 线程状态

     

    状态:

    创建线程的方法:

    public class NewThread implements Runnable{
        @Override
        public synchronized void run(){
        	while(true){ 
        		try {
    				//Thread.sleep(100);
        			wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
        		System.out.println("线程运行中...");
        	}
        }
        public static void main(String[] args) {
        	NewThread n=new NewThread();
        	
        	//初始化状态
    		Thread thread =new Thread(n); //创建线程,并执行线程任务
    
    		thread.start();  //启动线程
    		while(true){
    			synchronized (n) {
    				System.out.println("主线程执行了....");
    				try {
    					Thread.sleep(100);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				n.notifyAll();
    			}
    		}
    	}
    }
    

      

    public class Demo1 extends Thread{
    	public Demo1(String name){
    		super(name);
    	}
    	
        @Override
        public void run() {
        	// while(true){
        	while(!interrupted()){  //中断线程的推荐用法
        		 System.out.println(getName()+"线程执行了。。");
        		 try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
        	 }
        }
    
         public static void main(String[] args) {
    		Demo1 demo1=new Demo1("first-thread");
    		Demo1 demo2=new Demo1("second-thread");
    		
    		//守护线程
    		//demo1.setDaemon(true);
    		//deom2.setDaemon(true);
    		
    		demo1.start();
    		demo2.start();
    		
    		//中断线程
    		//demo1.stop();
    		demo1.interrupt();
    //		try {
    //			Thread.sleep(2000);
    //		} catch (InterruptedException e) {
    //			e.printStackTrace();
    //		}
    	}
    }
    

      

    public class Demo3 {
       public static void main(String[] args) {
    	   //匿名内部类,只是用一次
    	   new Thread(){
    		   public void run(){
    			   System.out.println("thread start...");
    		   };  
    	   }.start();
    	   
    	   new Thread(new Runnable() {
    		@Override
    		public void run() {
               System.out.println("thread start...");
    		}
    	}).start();
    	   
    	   //两个同时使用
    	   new Thread(new Runnable() {
    		@Override
    		public void run() {
    			System.out.println("runnable");
    		}
    	 }){
    		   public void run(){
    			   System.out.println("sub");
    		   };
    	   }.start();
       } 
    }
    

      

    import java.util.concurrent.Callable;
    import java.util.concurrent.FutureTask;
    
    //线程的返回值类型
    public class Demo4 implements Callable<Integer>{
    
    	public static void main(String[] args) throws Exception  {
    		Demo4 demo4=new Demo4();
    		FutureTask<Integer> task=new FutureTask<>(demo4);
    		Thread t=new Thread(task);
    		t.start();
    		task.get();
    		System.out.println("我先干点别的。。。。");
    		Integer result=task.get();
    		System.out.println("线程执行的结果为:"+result);
    	}
    	@Override
    	public Integer call() throws Exception {
    		System.out.println("正在进行紧张的计算");
    		Thread.sleep(300);
    		return 1;
    	}
    }
    

      定时器:

    import java.util.Timer;
    import java.util.TimerTask;
    
    public class Demo5 {
        public static void main(String[] args) {
    		Timer timer=new Timer();
    		timer.schedule(new TimerTask() {
    			
    			@Override
    			public void run() {
                    //实现定时任务
    				System.out.println("timertask is run");
    			}
    		},0,1000);
    	}
    }
    

      线程池:

    import java.util.concurrent.Executor;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Demo6 {
        public static void main(String[] args) {
        	//固定容量的线程池
    		//Executor threadPool=Executors.newFixedThreadPool(10);
    		//ExecutorService threadPool=Executors.newFixedThreadPool(10);
        	ExecutorService threadPool=Executors.newCachedThreadPool();
        	
    		for(int i=0;i<10;i++){
    			threadPool.execute(new Runnable() {
    				@Override
    				public void run() {
    					System.out.println(Thread.currentThread().getName());
    				}
    			});
    		}
    		threadPool.shutdown();
    	}
    }
    

      spring使用线程:

    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableAsync;
    
    @Configuration
    @ComponentScan("com.roocon.thread.t1")  //扫描的包
    @EnableAsync
    public class Config {
    
    }
    

      

    import org.springframework.scheduling.annotation.Async;
    import org.springframework.stereotype.Service;
    
    @Service   //交给spring管理
    public class DemoService {
    	@Async  //异步调用的注解
    	public void a() {
    		while (true) {
    			System.out.println("a");
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	public void b() {
    		while (true) {
    			System.out.println("b");
    			try {
    				Thread.sleep(200);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

      

    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class Main {
        public static void main(String[] args) {
    		AnnotationConfigApplicationContext ac=new 
    				AnnotationConfigApplicationContext(Config.class);
    		DemoService ds=ac.getBean(DemoService.class);
    		ds.a();
    		ds.b();
    	}
    }
    

      使用lambda表达式:

    import java.util.Arrays;
    import java.util.List;
    
    public class Demo7 {
    	public static void main(String[] args) {
    		List<Integer> value=Arrays.asList(10,20,30,40);
    		int res=new Demo7().add(value);
    		System.out.println("计算结果:"+res);
    	}
       public int add(List<Integer> values){
    	   //打印集合中的值  并行执行
    	   //values.parallelStream().forEach(System.out::println);
    	   //不是并行执行
    	   //values.stream().forEach(System.out::println);
    	   //并行执行排序
    	   values.parallelStream().forEachOrdered(System.out::println);
    	   return 0;
    	   //并发的流
    	   //return values.parallelStream().mapToInt(a->a).sum();
       }
    }
    

      线程带来的风险:

    1.线程安全问题

    2.活跃性问题(死锁、饥饿、活锁)

    3.性能问题

    饥饿与公平

    同时启动三个线程执行会有重复性数据:(与字节码有关)

    public class Sequence {
        private int value;
        public int getNext(){
        	value=value+1;
        	return value++;
        }
        public static void main(String[] args) {
        	Sequence sq=new Sequence();
        	//一个执行
    //		while(true){
    //			System.out.println(sq.getNext() );
    //		}
        	new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while(true){
    					System.out.println(
    							Thread.currentThread().getName()+""+
    					sq.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
        	new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while(true){
    					System.out.println(
    							Thread.currentThread().getName()+""+
    					sq.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
        	new Thread(new Runnable() {
    			@Override
    			public void run() {
    				while(true){
    					System.out.println(
    							Thread.currentThread().getName()+""+
    					sq.getNext());
    					try {
    						Thread.sleep(100);
    					} catch (InterruptedException e) {
    						
    						e.printStackTrace();
    					}
    				}
    			}
    		}).start();
    	}
    }
    

      解决方法:让方法变成同步方法。

      public synchronized int getNext(){
            return value++;
        }
    

      线程安全问题:

    1.多线程环境下

    2.多个线程共享一个资源

    3.对资源进行非原子性操作

     内置锁:每个对象都可以用同步的锁   synchronized  放在普通方法上,内置锁就是当前类的实例。修饰静态方法,内置锁是当前Class字节码对象,修饰代码块。

    互斥锁:一个线程进来,另一个线程就不能就来,保证了原子性

    任何对象都可以作为锁,锁的信息又存在对象的什么地方呢?

    存在对象头中

    对象头中的信息包括:

    1.Mark Word

    2.Class Metadata Address

    3.Array Length

    偏向锁:每次获取锁和释放锁会浪费资源

    很多情况下,竞争锁,不是由多个线程,而是由一个线程在使用。

    只有一个线程在访问同步代码块的场景

    轻量级锁:自旋,多个线程可以同时

    重量级锁:只能等当前线程执行完了,其他线程才能进去。

    锁重入:使用同一个对象才能锁的住,不同的对象是锁不住的。 

    public class Demo {
    	public synchronized void a(){
    		System.out.println("a");
    		//b();
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
    	public synchronized void b(){
    		System.out.println("b");
    		try {
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    	}
        public static void main(String[] args) {
        	 //Demo demo=new Demo();
        	Demo demo1=new Demo();
        	Demo demo2=new Demo();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				demo2.a();
    			}
    		}).start();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				demo1.b();
    			}
    		}).start();
    	}
    }
    

      自旋锁的应用:

    import java.util.Random;
    
    //多个线程执行完毕后,打印一句话,结束
    public class Demo2 {
        public static void main(String[] args) {
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+"执行开始....");
    				
    				try {
    					Thread.sleep(new Random().nextInt(2000));
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"执行完毕了...");
    			}
    		}).start();
    		
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+"执行开始....");
    				
    				try {
    					Thread.sleep(new Random().nextInt(2000));
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"执行完毕了...");
    			}
    		}).start();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+"执行开始....");
    				
    				try {
    					Thread.sleep(new Random().nextInt(2000));
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"执行完毕了...");
    			}
    		}).start();
    		new Thread(new Runnable() {
    			@Override
    			public void run() {
    				System.out.println(Thread.currentThread().getName()+"执行开始....");
    				
    				try {
    					Thread.sleep(new Random().nextInt(2000));
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName()+"执行完毕了...");
    			}
    		}).start();
    		
    		while(Thread.activeCount()!=1){
    			//自旋
    		}
    		//if(Thread.activeCount()==1)//活动线程的数量
    		    System.out.println("所有的线程执行完毕了");
    		
    	}
    }
    

      死锁:当一个线程永远的持有一把锁,并且其他线程尝试获取这把锁,也就发生了死锁

    public class Demo3 {
        private Object obj1=new Object();
        private Object obj2=new Object();
        
        public void a(){
        	synchronized (obj1) {
        		try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    			synchronized (obj2) {
    				System.out.println("a");
    			}
    		}
        }
        public void b(){
        	synchronized(obj2){
        		try {
    				Thread.sleep(10);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
        		synchronized (obj1) {
        			System.out.println("b");
    			}
        	}
        }
        public static void main(String[] args) {
        	Demo3 demo3=new Demo3();
    		new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				demo3.a();
    			}
    		}).start();
            new Thread(new Runnable() {
    			
    			@Override
    			public void run() {
    				demo3.b();
    			}
    		}).start();
    	}
    }
    

      

    单例中出现线程安全问题,懒汉和饿汉方式:

    public class Singleton {
    	//私有化构造方法,不让new
        private Singleton(){
        	
        }
        //饿汉式,创建的时候实例化(没有线程安全性问题)
        private static Singleton instance=new Singleton();
        
        public static Singleton getInstance(){
        	return instance;
        }
        
         //出现线程安全性问题的条件 
        //多线程的环境下
        //必须有共享资源
        //对资源进行非原子性操作
    }
    

      

    public class Main {
       public static void main(String[] args) {
    	Singleton s1=Singleton.getInstance();
    	Singleton s2=Singleton.getInstance();
    	Singleton s3=Singleton.getInstance();
    	Singleton s4=Singleton.getInstance();
    	
    	System.out.println(s1);
    	System.out.println(s2);
    	System.out.println(s3);
    	System.out.println(s4);
       }
    }
    

      

    public class Singleon2 {
       private Singleon2(){}
       //懒汉式
       private static volatile Singleon2 instance;
      // public static Singleon2 getInstance(){
       public static synchronized Singleon2 getInstance(){  //synchronized没有性能保证
    	   //自旋  while(true) 
    	   if(instance ==null){
    //		   try {
    //			Thread.sleep(100);
    //		} catch (InterruptedException e) {
    //			e.printStackTrace();
    //		}
    		   synchronized(Singleon2.class){ //锁住有问题的代码
    			   if(instance==null){
    				   instance =new Singleon2();  //双重检查加锁,还有指定重排序的问题
    				   //申请一块空间 1.
    				   //在这块空间中实例化对象2.
    				   //instance的引用指向这块空间地址3.
    				   //但是不一定这样执行,这就引发指令重排序
    				   //volatile 不会出现指令重排序
    			   }
    		   }
    	   }
    	   return instance;
       }
    }
    

      

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class MultiThreadMain {
        public static void main(String[] args) {
        	//固定线程池
    		ExecutorService threadPool=
    				Executors.newFixedThreadPool(20);
    		for(int i=0;i<20;i++){
    			threadPool.execute(new Runnable() {
    				
    				@Override
    				public void run() {
    					System.out.println(Thread.currentThread().getName()
    							+":"+Singleon2.getInstance());
    				}
    			});
    		}
    		threadPool.shutdown();
    	}
    }
    

      

  • 相关阅读:
    为什么要使用MQ消息中间件?
    趣图:这是招聘超神级别的程序员?
    基于redis的分布式锁的分析与实践
    我的java问题排查工具单
    趣图:看到这些窗户,我想插上几根网线
    SpringBoot+MyBatis+MySQL读写分离(实例)
    IntelliJ IDEA 常用快捷键
    ex3 多分类和神经网络
    9、神经网络的学习
    神经网络--反向传播详细推导过程
  • 原文地址:https://www.cnblogs.com/sunliyuan/p/11086740.html
Copyright © 2011-2022 走看看