进程线程的区别:
1、一个程序,可以有多个进程
2、一个进程可以有多个线程。但是必须要有一个主线程
3、进程间不能共享资源,但是线程间可以共享资源。
4, 进程时操作系统资源分配的基本单位,,而线程是CPU的基本调度单位。
线程创建方式:
1,继承Thread类:
编写简单、单继承,所以这种类无法再继承其他类、无法实现多个线程的资源共 享、扩展性无。
2,实现Runnable接口:
编写复杂一点,接口可以多实现,可以实现多个线程的资源共享 推荐使用
3,实现Callable接口:
编码复杂,可以实现线程执行完之后进行值的返回
【开发中需要线程返回值就使用Callable,不需要返回值的就可以Runnable5.8】
synchronized Java中的关键字,用来解决线程安全
有三种用法:
1.同步代码块
语法格式:方法内部
synchronized(引用类型对象){
要保护的代码
}
2.同步方法
语法格式:修饰方法
访问修饰符 synchronized 返回值 方法名(参数){
要保护的内容
}
3.同步静态方法
语法格式:修饰静态方法
访问修饰符 static synchronized 返回值 方法名(参数){
要保护的内容
}
题目理解
代码清单1
class MyThread extends Thread{
private String data;
public MyThread(String data){
this.data = data;
}
public void run() {
synchronized(data){
for(int i = 0; i<10; i++){
try{
Thread.sleep((int)(Math.random()*1000));
}catch(Exception e){}
System.out.println(data + "--" +i);
}
}
}
}
public class Test7 {
public static void main(String args[]) {
Thread t1 = new MyThread("hello");
Thread t2 = new MyThread("world");
t1.start();
t2.start();
}
}
答案时,hello world交替输出,那怎么操作锁才能让他们不会交替输出呢?
答案是传入的date不是同一个对象,所以它们的锁加的不同,并不能起作用。
改成synchronized(System.out)就可以分开,因为他们用同一个run方法,传入不同data
值,锁住输出语句,另一个线程只能等它执行完。
清单2
class MyThread1 extends Thread{
Object lock;
public MyThread1(Object lock){
this.lock = lock;
}
public void run(){
synchronized(lock){ //1
for(int i = 0; i<=10; i++){
try{
Thread.sleep( (int)(Math.random()*1000) );
}catch(Exception e){}
//System.out.print(lock);
System.out.println("$$$");
}
}
}
}
class MyThread2 extends Thread{
Object lock;
public MyThread2(Object lock){
this.lock = lock;
}
public void run(){
synchronized(lock){ //2
for(int i = 0; i<=10; i++){
try{
Thread.sleep((int)(Math.random()*1000) );
}catch(Exception e){
}
//System.out.print(lock);
System.out.println("###");
}
}
}
}
public class Test6{
public static void main(String args[]){
Object lock = new Object();
// Object lock1 = new Object();
Thread t1 = new MyThread1(lock);
Thread t2 = new MyThread2(lock);
t1.start();
t2.start();
}
}
答案是顺序输出,因为lock是同一个对象,同一个地址,可以有效锁住。
总结
锁:一个线程在访问临界资源的时候,加上锁,这时其他线程,访问临界资源,就会发 现已经上锁,就说明有其他线程在占用,这时就会在等待锁的释放
1,每个对象只有一把互斥锁标记,用来分配给线程
2,只有拥有对象互斥锁标记的线程,才能进入该对象的同步代码块
3,线程退出同步代码块时,会释放相应的互斥锁标记