JAVA--线程

39 篇文章 0 订阅
4 篇文章 0 订阅

目录

(一)定义

(二)如何创建一个线程

1、第一种:

2、第二种:

3、创建线程注意事项

(四)Thread的常用方法

        (五)线程的优先级

        (六)线程的休眠

          (七)线程的串行化

        (八)Synchronized同步

   1、修饰范围:

   2、作用:

        (九)生产消费问题


(一)定义

一个程序里不同的执行路径;

(二)如何创建一个线程

1、第一种:

a、创建一个继承Thread的类(假定类名为A),并重写Thread中的run方法;

b、构造一个A类对象(假定对象名是aa);

c、调用aa的steat方法(start方法由Thread继承而来);

class A extends Thread{//创建一个继承Thread的类
	public void run() {//重写Thread中的run方法
		while(true) {
		System.out.println("aaaa!");
		}
	}
}
public class TestA {
	public static void main(String[] args) {
		A aa=new A();
		aa.start();//调用aa的start方法,start方法生成一个新的线程,并自动调用aa的run方法
		while(true){
			System.out.println("bbbb!");
		}
	}
}

2、第二种:

a、定义一个实现Runnable接口的类(假定类名为B);

b、创建B类对象(假定为bb);

c、利用bb构建一个Thread对象(假定为tt);

        Thread tt=new Thread(bb)

d、调用tt的start方法;

class B implements Runnable{
	public void run() {
		while(true) {
			System.out.println("aaaaa!");
		}
	}
}
public class TestB {
	public static void main(String[] args) {
		B bb=new B();
		Thread tt=new Thread(BB);
		tt.start();
		//tt.start();//抛出异常
		while(true) {
			System.out.println("bbbbb!");
		}
	}
}

3、创建线程注意事项

a、Thread中的start方法的功能就是创建一个新的线程,并自动调用该线程的run方法,直接调用run方法并不会创建一个新的线程;

b、执行一个线程就是执行该线程的run方法里面的代码;

c、执行完aa.start();后并不代表该线程会立刻被执行,aa.start();执行后只是代表该线程获得了被CPU执行的资格,由于想抢占CPU执行的线程很多,aa所对应的线程不一定能抢到;

d、一个Thread对象有且只能代表一个线程,若一个Thread对象调用两个aa.start();程序会抛出异常;

 (四)Thread的常用方法

public final void setName(String name)(设置当前线程名字)

public static Thread currentThread()(返回当前正在执行的线程对象的引用)

public final void getName(String name)(返回当前线程的名字)

class A implements Runnable{
	public void run() {
		
		System.out.printf("%s正在运行\n",Thread.currentThread().getName());
	}
}
public class Threadcsdn {
	public static void main(String[] args) {
		A aa=new A();
		Thread tt1=new Thread(aa);
		Thread tt2=new Thread(aa);
		
		tt1.start();
		tt1.setName("线程一");
		
		tt2.start();
		tt2.setName("线程二");
		
		System.out.printf("%s正在运行\n",Thread.currentThread().getName());
	}

执行结果:main正在运行
                 线程二正在运行
                 线程一正在运行

(五)线程的优先级

1、int getPriority();(获得线程的优先级数级)

void setPriority(int newPriority);(设置当前线程的优先级)

2、优先级由数字表示,范围1~10逐渐递增;

3、默认优先级为5,子类默认优先级与父类一样;

4、优先级高不一定优先执行,只是提高可能性。

(六)线程的休眠

1、线程的休眠是指暂停当前线程的执行,使之进入堵塞状态,待经过指定“延迟时间”后便醒来进入就绪状态;

2、public static void sleep(long millis);

3、sleep方法调用时会抛异常,需要进行抓捕;

class A extends Thread{
	public void run() {
		for(int i=0;i<10;i++) {
			System.out.printf("%s--%d正在执行\n",Thread.currentThread().getName(),i);
			try {
				Thread.sleep(1000);
			}
			catch(Exception e) {
			}
		}
	}
}
public class sleepcsdn {
	public static void main(String[] args) {
		A aa=new A();
		aa.start();
	}
}

运行结果: Thread-0--0正在执行
                   Thread-0--1正在执行
                   Thread-0--2正在执行
                   Thread-0--3正在执行
                   Thread-0--4正在执行
                   Thread-0--5正在执行
                   Thread-0--6正在执行
                   Thread-0--7正在执行
                   Thread-0--8正在执行
                   Thread-0--9正在执行

4、重写的run方法不能抛出异常,原因是重写方法的异常不能大与被重写方法的异常范围。

(七)线程的串行化

1、public final void join(); throw~

class A implements Runnable{
	public void run() {
		for(int i=0;i<5;i++)
			System.out.println(i);
	}
}
public class TestJoin {
	public static void main(String[] args) {
		A aa=new A();
		Thread tt=new Thread(aa);
		tt.start();
		try {
			tt.join();//暂停当前正在执行的tt.join();线程,知道t所对应的线程终止之后,当前线程                
                      //才获得继续执行的机会(这里暂停的是主线程)
		}
		catch(Exception e) {
		}
		for(int t=5;t<10;t++) {
			System.out.println(t);
		}
	}
}

运行结果:0
                  1
                  2
                  3
                  4
                  5
                  6
                  7
                  8
                  9

(八)Synchronized同步

1、修饰范围:

 a、一个方法;

 b、一个方法里面的代码块;

2、作用:

a、修饰代码块格式:

synchronized(类对象名 aa){

        同步代码块;

}

b、synchronized(类对象名 aa)含义:判断aa是否被其它线程锁定,如果发现aa被其他线程锁定,则当前线程陷入等待,若aa没有被其它线程锁定,则当前线程锁定aa对象,并执行同步代码块,此时其它线程在同步代码块未执行完前都无法执行,待同步代码块执行完后,该线程自动释放aa的锁定,其它线程再次相互竞争对aa的锁定;

c、结果:一个线程在操作某资源时,将不允许其它线程操作该资源,即一次只允许一个线程操作该资源。

d、synchronized修饰一个方法时,实际上时锁定this指针指向的对象;

class A implements Runnable{
	public static int tickets=1000;
	public  void run() {
	String str="haha!";
	while(tickets>0)synchronized(str) {
	     System.out.printf("%s已卖出第%d张票\n",Thread.currentThread().getName(),tickets);
						--tickets;	
	 }
  }
}
public class maipiao {
	public static void main(String[] args) {
		A aa=new A();
		Thread tt1=new Thread(aa);
		Thread tt2=new Thread(aa);
		tt1.start();
		tt2.start();
	}
}

(九)生产消费问题

1、aa.wait();

将执行aa.wait的线程转入堵塞状态;

2、aa.notify();

如果所处的线程进入堵塞状态,则将其它陷入堵塞状态的线程其中一个转为就绪状态;

class A{
		private char[] date=new char[6]; 
		private int cnt=0;


		public synchronized void pust(char a) {
			while(cnt==date.length) {
					try {
						this.wait();
					}
					catch(Exception e) {
		 
					}
			}
			this.notify();	
			date[cnt++]=a;
			System.out.printf("第%d个生产成功,为:%s\n",cnt,date[cnt-1]);
				
	}
		public synchronized char pop() {
				char ch;
				while(cnt==0) {
					try {
						this.wait();
					}
					catch(Exception e) {
	 
					}
				}
				this.notify();
				ch=date[cnt-1];
				cnt--;
				System.out.printf("第%d个消费成功,为:%s\n",cnt+1,ch);
				return ch;
			}
	}
	class B implements Runnable{
		private A bb=null;
		public B(A aa) {
			bb=aa; 
		}
		char st;
		public void run() {
		for(int u =0;u<20;u++) {
			st=(char)('a'+u);
			bb.pust(st);
		}
	    	 
		}
	}
	class C implements Runnable{
		private A cc=null;
		public C(A aa) {
		   cc=aa;
		}
		public void run() {
	     for(int u =0;u<20;u++)
	    	 cc.pop();
		}
	}
	public class TestSx {
		public static void main(String[] args) {
		A aa=new A();
		B bb=new B(aa);
		C cc=new C(aa);
		Thread sh=new Thread(bb);
		Thread xi=new Thread(cc);
		sh.start();
		xi.start();

		}
	}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值