2.Java基础:线程和同步

1.什么是线程

线程是进程的一个单元片段,多个线程组合到一起,完成一个进程。


2.创建线程方式

第一种创建方式

1.extends Thread类,这个类是在java.lang包下。这个类代表的就是线程。

2.继承Thread类时,必须重写run方法,run方法中定义的是我们的线程要执行的内容.

3.启动一个线程要调用Thread类中的start方法。


以下例子就是这种创建方式

//线程创建
public class five extends Thread {
	public static void main(String[] args) {
		//第一种方式:继承Therad类,重写run
		five td = new five(); //创建一个线程
		
		td.run(); //调用run方法,不是线程
		
		td.start(); //启动线程
	}
	
	//重写run方法
	@Override
	public void run() {
		System.out.println("hello run");
	}
}

以上代码在执行时:

1.程序加载到jvm后,jvm会辟一条通道,去运行main线程。

2.main线程执行,它会执行main方法中的内容,这时会创建一个ThreadDemo1对象,

这个对象就是一个线程对象,

3.通过这个对象调用了start方法,这时jvm会在开辟一条通道去运行run方法中的内容。                         

4.也就是说,对于当前这个程序,

它有两个通道,一个是main通道,一个是td通道。


第二种创建方式

1.implements Runnable(推荐)

2.在启动线程时使用的是:new Thread(实现了Runnable接口的类的对象).start();


以下例子就是这种创建方式

//第二种实现线程方法(接口)
public class seven implements Runnable {
	
	public static void main(String[] args) {
		//开启线程
		seven s = new seven();
		new Thread(s).start();
		
		for (int i = 0; i < 10; i++) {
			System.out.println("main"+i);
		}
	}
	
	//线程要执行的内容
	public void run() {
		for (int i = 0; i < 10; i++) {
			System.out.println("run"+i);
		}	
	}
}
注意:线程在执行时,它具有无序性。


3.线程执行状态

1.创建
2.运行
3.结束
4.冻结
5.临时堵塞


4.线程安全问题

1.出现安全问题条件

1.多线程.

2.多个线程共享数据.

3.共享的数据被多条语句操作

为了更好阐述死锁,下面将使用一个例子来说明。

//演示死锁
public class thirteen {
	public static void main(String[] args) {
		Thread2 mt = new Thread2();
		
		//创建2个线程
		Thread th1 = new Thread(mt);
		Thread th2 = new Thread(mt);
		
		//自定义线程名
		th1.setName("first");
		th2.setName("second");
		
		//开启线程
		th1.start();
		th2.start();
	}
}

class Thread2 implements Runnable {
	@Override
	public void run() {
		// TODO Auto-generated method stub
		//线程内容
		if (Thread.currentThread().getName().equals("first")) {
			first();
		} else {
			second();
		}
	}
	
	public void first() {
		synchronized(Globle.obj1) {
			try {
				Thread.sleep(1); //休眠1秒,得到obj1锁
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			synchronized(Globle.obj2) { //发现th2线程拿着这把锁,等待obj2释放
				System.out.println("first");
			}
		}
	}
	
	public void second() {
		synchronized(Globle.obj2) { //th2线程,得到obj2这把锁向下执行
			synchronized(Globle.obj1) { //只有得到obj1这把锁才可向下执行
				System.out.println("second");
			}
		}
	}
}

class Globle {
	//以下2个对象作为锁对象
	public static final Object obj1 = new Object();
	
	public static final Object obj2 = new Object();
}

2.解决安全问题:锁机制

第一种:synchronized块(同步块)

synchronized(任意对象){

要锁定代码

}

锁对象就是 this

注意:多个线程所使用的锁对象必须是同一个。

以下例子就是这种锁机制

//线程安全,用锁解决
public class twelve {
	public static void main(String[] args) {
		Thread1 mt = new Thread1();
		// 创建两个线程
		Thread th1 = new Thread(mt);
		Thread th2 = new Thread(mt);
		
		//开启线程
		th1.start();
		th2.start();
	}
}

class Thread1 implements Runnable {
	int count = 10; //共享数据
	
	public void run() { //使用是main函数类中的对象
		synchronized(this) {
			count++;
			
			try {
				Thread.sleep(1); //线程睡眠1秒
				//因为th1线程使用了同步块,这时,th2线程等待,th1线程休眠结束,继续执行
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			System.out.println(count);	//th1线程结束。释放了锁。这时th2才可以执行。
		}
	}
}




第二种:synchronized方法(同步方法

synchronized做为一个修饰符去修饰方法。

1.非static方法。   锁对象就是 this

2.static方法        锁对象就是  类名.class.

以下例子就是这种锁机制

//线程安全,用锁解决
public class twelve {
	public static void main(String[] args) {
		Thread1 mt = new Thread1();
		// 创建两个线程
		Thread th1 = new Thread(mt);
		Thread th2 = new Thread(mt);
		
		//开启线程
		th1.start();
		th2.start();
	}
}

class Thread1 implements Runnable {
	static int count = 10; //共享数据
	
	@Override
	public void run() {
		count++;
		
		synchronized(Thread1.class) { //当前同步代码块所使用的锁是本类的对象
			try {
				Thread.sleep(1); //休眠1秒
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			System.out.println(count);
		}
		
	}
}
总结:static 同步函数,使用的锁不是this,而是字节码文件对象, 类名.class 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6527) at javax.swing.JComponent.processMouseEvent(JComponent.java:3321) at java.awt.Component.processEvent(Component.java:6292) at java.awt.Container.processEvent(Container.java:2234) at java.awt.Component.dispatchEventImpl(Component.java:4883) at java.awt.Container.dispatchEventImpl(Container.java:2292) at java.awt.Component.dispatchEvent(Component.java:4705) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462) at java.awt.Container.dispatchEventImpl(Container.java:2278) at java.awt.Window.dispatchEventImpl(Window.java:2739) at java.awt.Component.dispatchEvent(Component.java:4705) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746) at java.awt.EventQueue.access$400(EventQueue.java:97) at java.awt.EventQueue$3.run(EventQueue.java:697) at java.awt.EventQueue$3.run(EventQueue.java:691) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86) at java.awt.EventQueue$4.run(EventQueue.java:719) at java.awt.EventQueue$4.run(EventQueue.java:717) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75) at java.awt.EventQueue.dispatchEvent(EventQueue.java:716) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
07-14

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值