线程、同步
1.多线程原理
package demo01;
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name) {
super();
this.name = name;
}
public Person() {
super();
}
public void run() {
for(int i=0;i<20;i++) {
System.out.println(name+"-->"+i);
}
}
}
package demo01;
/*
* 主线程 执行main()方法的线程
*
* 单线程程序:只有一个线程在执行,从头到尾
* */
public class demo01MAainThread {
public static void main(String[] args) {
Person p1=new Person("小强");
p1.run();
//System.out.println(0/0);
Person p2=new Person("小刚");
p2.run();
}
}
2.创建线程方式
package demo01;
//1.创建Thread子类
public class MyThread extends Thread{
//2.重写run方法
public void run() {
for(int i=0;i<20;i++) {
System.out.println("子线程:"+i);
}
}
}
package demo01;
/*
* java.long.Thread
*
* 实现步骤:
* 1.创建一个Thread类的子类
* 2.在Thread子类中重写run方法,设置线程任务(干什么)
* 3.创建Thread子类的对象
* 4.调用Thread类中的方法来启动线程,执行run方法
*
* */
public class demo01Thread {
public static void main(String[] args) {
//3.创建Thread子类的对象
MyThread mt=new MyThread();
//4.调用start方法
mt.start();
for(int i=0;i<20;i++) {
System.out.println("主线程:"+i);
//if(i==10)
//System.out.println(0/0);
}
}
}
3.Thread和Runnable的区别
Thread
package demo02;
public class MyThreadName extends Thread{
public MyThreadName() {
}
public MyThreadName(String name) {
super(name);//把线程的名字传递给父类,让父类Thread给子线程起一个名字
}
public void run() {
//String name=getName();
//System.out.println("run:"+name);
System.out.println("子:"+Thread.currentThread().getName());
}
}
package demo02;
/*
* java.long.Thread
*
* 实现步骤:
* 1.创建一个Thread类的子类
* 2.在Thread子类中重写run方法,设置线程任务(干什么)
* 3.创建Thread子类的对象
* 4.调用Thread类中的方法来启动线程,执行run方法
* */
public class demo01Thread {
public static void main(String[] args) {
//3.创建Thread子类的对象
MyThread mt=new MyThread();
//4.调用start方法
mt.start();//子进程0
new MyThread().start();//子进程1
new MyThread().start();//子进程2
new MyThread().start();//子进程3
System.out.println("main:"+Thread.currentThread().getName());
}
}
Runnable
package demo02;
public class demo02ThreadSetName {
public static void main(String[] args) {
MyThreadName mt=new MyThreadName("小强");
mt.start();
new MyThreadName("张三").start();
}
}
package demo02;
//1.创建Thread子类
public class MyThread extends Thread{
//2.重写run方法
public void run() {
//String name=getName();
//System.out.println("run:"+name);
System.out.println("子"+Thread.currentThread().getName());
}
}
Timed Waiting(计时等待)
package demo03;
public class demo03Sleep {
public static void main(String[] args) {
for(int i=1;i<100;i++) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Runnable和runnable
package demo04;
/*
* 实现runnable接口创建多线程的好处:
* 1.避免了单继承的局限性
* 2.增强了程序的拓展性,降低了程序的耦合性
* */
public class demo04Runnable {
public static void main(String[] args) {
//3.创建一个runnable接口的实现类对象
//RunnableImpl run=new RunnableImpl();
//4.创建Thread类对象,构造方法中传递Runnable接口实现类对象
//Thread t=new Thread(run);
//5.调用Thread类中的start方法,启动子线程
Thread t=new Thread(new RunnableImpl2());
t.start();
for(int i=0;i<20;i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
package demo04;
public class RunnableImpl2 implements Runnable{
@Override
public void run() {
for(int i=0;i<20;i++) {
System.out.println("HelloWorld-->"+i);
}
}
}
package demo04;
//1.创建一个runnable接口的实现类
public class RunnableImpl implements Runnable {
//2.在实现类中 重写runnable的run方法,设置线程任务
@Override
public void run() {
for(int i=0;i<20;i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}
线程安全
package demo05;
public class demo01Ticket {
public static void main(String[] args) {
RunnableImpl run=new RunnableImpl();
Thread t0=new Thread(run);
Thread t1=new Thread(run);
Thread t2=new Thread(run);
t0.start();
t1.start();
t2.start();
}
}
package demo05;
/*
* 解决线程安全问题的一种方案:使用同步代码块
* 格式:
* synchronized(锁对象){
* 可能会出现线程安全的代码(是因为访问了共享的数据)
* }
* 注意:
* 1.通过代码块中的锁对象,可以使用任意的对象
* 2.但是必须保证多个线程使用的锁对象是同一个
* 3.锁对象
* 把同步代码块锁住,只让一个线程执行
*
**/
public class RunnableImpl implements Runnable{
private int ticket=100;
Object obj=new Object();
@Override
public void run() {
while(true) {
synchronized(obj){
if(ticket>0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->正在卖第"+ticket+"张票");
ticket--;
}
}
}
}
}
2020080605012