java-高级特性 多线程

继承thread类实现多线程

package com.bxy.thread;

class MyThread extends Thread{
private String title;

 public MyThread(String title) {
	 this.title=title;
 }
 
public void run() {
	System.out.println("线程启动");
	for(int i=0;i<10;i++) {
		
		System.out.println("x="+i);
	}
	
}

}

public class JavaDemo {
public static void main(String[] args) {

	      MyThread thread1=new MyThread("线程1");
	      MyThread thread2=new MyThread("线程2");
	      MyThread thread3=new MyThread("线程3");
			thread1.start();
			thread2.start();
			thread3.start();
	  
	
}

}

实现Runnable接口实现多线程

package com.bxy.thread;

class MyThread implements Runnable{
private String title;

 public MyThread(String title) {
	 this.title=title;
 }
 
public void run() {
	System.out.println(title+"启动");
	for(int i=0;i<10;i++) {	
		System.out.println("x="+i);
	}
	
}

}

public class JavaDemo {
public static void main(String[] args) {

	Thread thread1=new Thread(new MyThread("线程1"));
	Thread thread2=new Thread(new MyThread("线程2"));
	Thread thread3=new Thread(new MyThread("线程3"));
	thread1.start();
	thread2.start();
	thread3.start();
	
	
}

}

使用lambda(匿名函数)实现多线程定义

public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
String title = “线程” + i;
Runnable run = () -> {
for (int j = 1; j <= 10; j++) {
System.out.println(title + “运行喽,y=” + j);
}
};
new Thread(run).start();
}
}

简化代码

public static void main(String[] args) {
for (int i = 1; i <= 3; i++) {
String title = “线程” + i;
new Thread(() -> {
for (int j = 1; j <= 10; j++) {
System.out.println(title + “运行喽,y=” + j);
}
}).start();
}
}

实现Callable接口实现多线程

package com.bxy.thread;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyThread implements Callable{
private String name;
public MyThread(String name) {
this.name=name;
}

@Override
public String call() throws Exception {
	// TODO Auto-generated method stub
	System.out.println(name+"正在开始执行😀");
	  for(int i=0;i<10;i++) {
		  System.out.println("线程正在执行,x="+i);
	  }
	
	return "线程"+name+"执行完毕😗";
}

}

	public class JavaDemo {
       public static void main(String[] args) {
	 FutureTask<String> task1=new FutureTask<String>(new MyThread("线程ONE"));
	 FutureTask<String> task2=new FutureTask<String>(new MyThread("线程TWO"));
	 FutureTask<String> task3=new FutureTask<String>(new MyThread("线程THREE"));
   new Thread(task1).start();
   new Thread(task2).start();
   new Thread(task3).start();

}

}
获取线程名称,对单个线程进行控制

	(使用Thread.currentThread().getName()//获取线程名称)

package com.bxy.thread;

class MyThread implements Runnable {
@Override
public void run() {
System.out.println(“当前的线程对象是”+Thread.currentThread().getName());

}
}public class JavaDemo {
public static void main(String[] args) {
 MyThread mt=new MyThread();
 mt.run();
 new Thread(mt,"线程1").start();
 new Thread(mt).start();
 new Thread(mt,"线程2").start();
	
}

}

所有线程是在一个主线程中实现调用,相当于主线程去分配任务,自己不去干一些浪费事件的事情

线程的休眠

(使用Thread.sleep()对线程进行休眠)

	、	public static void main(String[] args) {
          	MyThread mt = new MyThread();
	          for (int i = 1; i <= 5; i++) {
		        new Thread(() -> {
		          	for (int j = 0; j <= 10; j++) {
				    System.out.println(Thread.currentThread().getName() + "j=" + j);
			     	try {
					Thread.sleep(1000);
			      	} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, "线程对象" + i).start();
		;

	}

}
运行后会发现 这5个线程好像是同时进入休眠,又同时进行启动,但实际上并不是如此,线程总会有一个先来后到,但不排除,运行很快时,出现线程同步的事件

线程中断

(使用thread.interupet()对线程进行中断)
线程中断会抛出线程中断异常

public static void main(String[] args) throws InterruptedException {
	  Thread thread=new Thread(()->{
		
		 try {
			 System.out.println("奋斗了三天三夜,我要睡觉啦");
			Thread.sleep(10000);
			 System.out.println("哇,一觉睡醒了的感觉真好");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
		System.out.println("不嘛,/(ㄒoㄒ)/~~,我还要接着睡嘛");
		}

		 
	 });
	 thread.start();
	 Thread.sleep(1000);
	 if(!thread.isInterrupted()) {
		 System.out.println("毕大宇,起床吃饭啦!");
		 thread.interrupt();
	 }
	   
	
}

线程的强制执行

通过 mainThread.join() 表示mainThread这个线程要加入进来啦,而且是独占。

public static void main(String[] args) throws InterruptedException {
     Thread mainThread=Thread.currentThread();
	 Thread thread=new Thread(()->{
	  
		 for(int i=0;i<=100;i++) {
			 if(i==3) {
				 System.out.println("我要开始霸道起来啦");
				 try {
					mainThread.join();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			 }
			 System.out.println(Thread.currentThread().getName()+"执行中,i="+i);
			 try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		 }
		 
		 
	   
  },"玩耍的线程");
	 thread.start();
	 System.out.println("我要开始霸道起来啦");
	 for(int i=0;i<=100;i++) {
		
		 System.out.println("老子是霸道的线程,我要捏碎你i="+i);
		 Thread.sleep(100);
	 }
	 
}

线程的礼让

(使用Thread.yield()方法,礼让当前线程,让别的线程先去执行)
礼让执行的时候每一次调用yield()方法都只会礼让一次当前的资源

public static void main(String[] args) throws InterruptedException {
         Thread mainThread=Thread.currentThread();
	     Thread thread=new Thread(()->{
		 for(int i=0;i<=100;i++) {
	      if(i%3==0) {
	    	  Thread.yield();
	    	  System.out.println("我讲礼貌的,你👍,你先来");
	    	  
	      }
			 
			 System.out.println(Thread.currentThread().getName()+"执行中,i="+i);
			 try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		 }
		
  },"玩耍的线程");
	 thread.start();
	
	 for(int i=0;i<=100;i++) {
		
		 System.out.println("老子是霸道的线程,我要捏碎你i="+i);
		 Thread.sleep(100);
	 }
	 
}

线程的优先级

设置优先级后,只是提高了可能性,并不是确定的优先级
public static void main(String[] args) throws InterruptedException {
	
	Runnable run=()->{
		for(int i=1;i<=10;i++) {
			
			System.out.println(Thread.currentThread().getName()+"执行i="+i);
		
		  try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		
	};
	
	Thread threadA=new Thread(run,"线程A");
	Thread threadB=new Thread(run,"线程B");
	Thread threadC=new Thread(run,"线程C");
	threadA.setPriority(Thread.MAX_PRIORITY);
	threadB.setPriority(Thread.MIN_PRIORITY);
	threadC.setPriority(Thread.MIN_PRIORITY);
	threadA.start();	
	threadB.start();
	threadC.start();

}
线程同步问题的引出
package com.bxy.thread;

class MyThread implements Runnable {

private int ticket=10;
public void run() {

	while(true) {
		if(ticket>0) {
	       try {
			Thread.sleep(10);
			System.out.println(Thread.currentThread().getName()+"卖票,票数还剩"+ticket--);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
		}else {
			System.out.println("------------不好意思,票已经卖完啦--------------");
			break;
		}
	}
	
}

}

public class JavaDemo {
public static void main(String[] args) {

	      MyThread mt=new MyThread();
	      new Thread(mt,"票贩子A").start();
	      new Thread(mt,"票贩子B").start();
	      new Thread(mt,"票贩子C").start();
         
}

}
在这里插入图片描述
运行代码后会出现票数为0,甚至-1的情况出现,为什么呐?
因为run()方法中加入了sleep()方法,使线程进入了休眠,我们可以知道当票数等于1时,会进入if判断,并且该线程会进入休眠状态。此时,该线程并未重新启动时(相应的不会去执行–的操作,所以票数也没有更改),而另一个线程的票数仍然是1,所以该线程继续进入了if判断。。。。。。
所以,当多个线程访问同一资源时,如何解决数据的完整性,就成了一个问题?

线程同步

synchronized关键字便可以实现线程的同步处理,但同步处理会降低性能,synchronized相当于一个房间,只能允许一个线程进入,当房间里有线程存在时,别的线程只能够等待,想进来可以,等我出来。

class MyThread implements Runnable {

private  int ticket=10;
public synchronized boolean sales() {

	if(ticket>0) {
	       try {
			Thread.sleep(10);
			System.out.println(Thread.currentThread().getName()+"卖票,票数还剩"+ticket--);
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	       return true;
		}else {
			System.out.println("------------不好意思,票已经卖完啦--------------");
			return false;
		}
	}

public void run() {
	while(this.sales()) {
		
	}
}

}

public class JavaDemo {
public static void main(String[] args) {

	      MyThread mt=new MyThread();
	      new Thread(mt,"票贩子A").start();
	      new Thread(mt,"票贩子B").start();
	      new Thread(mt,"票贩子C").start();
         
}

}

线程死锁

package com.bxy.thread;

import com.sun.org.apache.xerces.internal.parsers.CachingParserPool.SynchronizedGrammarPool;
public class JavaDemo implements Runnable{

private LiHuiHui lhh=new LiHuiHui();
private BiXingYu bxy=new BiXingYu();

public static void main(String[] args)  {
	  new JavaDemo();
}

  public JavaDemo() {
	  new Thread(this).start();
	  bxy.say(lhh);
  }
@Override
public void run() {
	// TODO Auto-generated method stub
	lhh.say(bxy);
}

}
class LiHuiHui{

public synchronized void say(BiXingYu bxy) {
	System.out.println("lhh:此路是我开,此树是我栽,想要从这过,留下两毛钱");
	bxy.get();
}
public synchronized void get() {
	System.out.println("lhh:哈哈哈,买仔仔棒吃去喽");
}

}
class BiXingYu{
public synchronized void say(LiHuiHui lhh) {
System.out.println(“bxy:你先让我过去,我再给你钱嘛”);
lhh.get();
}
public synchronized void get() {
System.out.println(“bxy:哼,乘机赶紧跑咯”);
}

}
死锁造成的主要原因是因为彼此都在互相等待着,等待着对方先让出资源。死锁实际上是一种开发中不确定的状态,有的时候,代码处理不当则会不定期出现死锁,这是属于正常开发中的调试问题.
若干个线程访问统一资源是一定要进行同步处理,而过多的同步会造成死锁。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值