线程
我理解的是:从main方法进线程栈到所有的方法执行出来,然后main方法出栈,一条线的执行完成,叫线程;
线程栈与栈帧的关系
线程栈里面的方法都是拷贝过来的称为栈帧;每一个方法都是帧;

关于类锁和对象锁
假如有两个方法,在其中一个方法上加上锁(synchronized),这两个方法就不会锁上;
如果是两个静态方法,在方法前加上锁,就会一起锁上,先执行第一个方法,然后执行第二个方法;这个就是类锁;
如果是两个非静态的方法,那么在方法前加上锁,就会一起锁上,先执行第一个方法,然后执行第二个方法;这个就是对象锁;
也就是说,静态的方法加锁互相锁上,非静态的互相锁上;
注意:能够互相锁上的方法必须指向同一个内存区域,只有产生占用时用锁才能提升效率
ps:(静态方法和非静态方法的区别:在public中有static的是静态方法,没有的是非静态方法)

多线程
当产生CPU浪费时,为了提升效率,可以用多线程,用多个线程互相一起执行,为了防止产生堵塞,在方法里面加入锁,用来控制方法的执行;

以上就是我对这些概念的简单理解
下面我写一个关于多线程的简单的卖票程序;

首先我们写线程里面的东西;

public class ThreadTest extends Thread{//这里继承于java的Thread类
      private DataTest data;//线程内部的对象
      private String  name;

      ThreadTest(DataTest data,String name){
          this.data = data;
          this.name = name;
      }

      public void run() {//run方法是线程里面的特殊方法,一开始先执行run方法
          FlagTest f = new FlagTest();
          while( f.flag == 0) {//设定一个因素,可以开始run方法
              data.method3(name,f);
          }
      }
}

我们新建一个类,然后写一个条件,为了让run方法顺利执行

public class FlagTest {

    public int flag = 0;

}

下面我们开始写线程

public static void main(String[] args) {
        // TODO Auto-generated method stub

        DataTest test = new DataTest();
        ThreadTest t1 = new ThreadTest(test,"窗口1");
        ThreadTest t2 = new ThreadTest(test,"窗口2");
        ThreadTest t3 = new ThreadTest(test,"窗口3");
        t1.start();
        t2.start();
        t3.start();
    }

我们创建了三个线程
下面我们写线程里面改运行的方法,这里我写了一个关卖票的方法,建议放在一个新的类里面

    private static int ticket = 10000;//因为有锁的关系,所以定义了一个静态的数值,代表票的数量
    public  synchronized void method3(String name,FlagTest f) {
        if( ticket == 0) {//如果买完了
            f.flag = 1;//flag变化,run方法没办法用了,线程结束
            System.out.println("票卖完毕了");
            return;
        }
        System.out.println(name + "卖出了第" + ticket);
        ticket = ticket - 1;
    }

当我们写线程的时候,一个方法里面最好包含了读和写,因为读和写放在两个方法里会产生线程安全的问题;
就这一个锁,可能看不出来锁的是什么,列举一个例子:

//我们假设我们想调用树里面的数值去运算
    public synchronized void run() {
      while(tree.value<10)
      {
        tree.value++;      
      }    
    } 

方法里面加了锁,那么锁的是什么呢,锁的是tree,把树给锁上了
我们想要锁上树里面的数值应该怎样写呢?

public synchronized void run() {
      while(tree.value<10)
      {
          tree.yunshuan();//这里我们是把树给锁上了,包括里面的运算方法

      }    
    } 

然后在树里面写一个yunshuan的方法

//    正确锁上锁内部引用资源
    public synchronized void yunshuan() {
            value=value+1;

    }

这样就可以把树里面的东西给锁上了;

其实总结一下线程,我认为,线程里面一开始都有一个run方法,在开始线程的时候,先把需要用到拷贝一份,然后去执行;
如果是多线程,会存在可能拷贝不一样的,跟上一个不一样,在并发高的地方更容易产生不一样的线程;
线程拷贝只能拷贝栈里面的数据,堆里面的不能拷贝,在进行线程栈的时候,和顺序相关的进入栈里面,跟顺序无关的进入堆里面,变量栈里面存的是堆里面的地址,在堆里面运行,当发生了多个线程同时调用同一个地址时,会发生堵塞,这时候加锁,使其顺序运行,大大提升了效率,减少堵塞的情况;这就是线程和锁的关系;
对于线程和锁的理解还是比较浅的,而且大晚上了,可能有些错误,希望路过的各位大佬给一些建议,我会时时改进,祝大家新年快乐,